Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rajinderSiddhu committed Mar 4, 2021
0 parents commit 8246951
Show file tree
Hide file tree
Showing 37 changed files with 5,325 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: CI

on: [push, pull_request]

jobs:
build:
name: Build Plugin
runs-on: ubuntu-latest
steps:
- name: checkout code
uses: actions/checkout@v2
- name: set up java
uses: actions/setup-java@v1
with:
java-version: 11
- name: run tests
run: ./gradlew test
- name: build
run: ./gradlew releaseBundle
- name: archive build artifacts
uses: actions/upload-artifact@v1
with:
name: dist
path: build/distributions
24 changes: 24 additions & 0 deletions .github/workflows/compatibility.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Run Compatibility Test

on:
repository_dispatch:
types: CompatibilityTest

jobs:
test:
name: Test Plugin
runs-on: ubuntu-latest
steps:
- name: checkout code
uses: actions/checkout@v2
with:
ref: ${{ github.event.client_payload.sha }}
- name: set up java
uses: actions/setup-java@v1
with:
java-version: 11
- uses: armory-io/plugin-test-runner@main
with:
service: ${{ github.event.client_payload.service }}
version: ${{ github.event.client_payload.version }}
plugin_sha: ${{ github.event.client_payload.sha }}
97 changes: 97 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Release

on:
push:
tags:
- 'v*'

jobs:
build:
name: Release Plugin
runs-on: ubuntu-latest
steps:
- name: checkout code
uses: actions/checkout@v2

- name: set up java
uses: actions/setup-java@v1
with:
java-version: 11

- name: run tests
run: ./gradlew test

- name: build
run: ./gradlew releaseBundle

- name: get project info
id: get_project_info
run: |
echo ::set-output name=PROJECT::$(basename `pwd`)
echo ::set-output name=PROJECT_KEBAB::$(basename `pwd` | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\L\2/g')
echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
- name: create release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false

- name: upload release asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./build/distributions/${{ steps.get_project_info.outputs.PROJECT }}-${{ steps.get_project_info.outputs.VERSION }}.zip
asset_name: ${{ steps.get_project_info.outputs.PROJECT }}-${{ steps.get_project_info.outputs.VERSION }}.zip
asset_content_type: application/zip

- name: build docker image
id: build-docker-image
run: |
docker build -t gcr.io/cloud-armory/${{ steps.get_project_info.outputs.PROJECT_KEBAB }}:${{ steps.get_project_info.outputs.VERSION }} -f ./Dockerfile .
docker save -o ./${{ steps.get_project_info.outputs.PROJECT_KEBAB }}-${{ steps.get_project_info.outputs.VERSION }}.tar gcr.io/cloud-armory/${{ steps.get_project_info.outputs.PROJECT_KEBAB }}:${{ steps.get_project_info.outputs.VERSION }}
- name: upload image to release
id: upload-image-to-release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./${{ steps.get_project_info.outputs.PROJECT_KEBAB }}-${{ steps.get_project_info.outputs.VERSION }}.tar
asset_name: ${{ steps.get_project_info.outputs.PROJECT_KEBAB }}-${{ steps.get_project_info.outputs.VERSION }}.tar
asset_content_type: application/zip

- name: upload release asset for deck
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./random-wait-deck/build/dist/index.js
asset_name: RandomWaitStageIndex.js
asset_content_type: text/javascript

- name: add release to plugin repo
run: |
curl -XPOST -u "${{ secrets.USERNAME }}:${{ secrets.TOKEN }}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/spinnaker-plugin-examples/examplePluginRepository/dispatches --data "{\"event_type\": \"onPluginRelease\", \"client_payload\": {\"org\": \"spinnaker-plugin-examples\", \"repo\": \"${{ steps.get_project_info.outputs.PROJECT }}\", \"released\": $(cat build/distributions/plugin-info.json)}}"
- name: setup gcloud
uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
with:
project_id: cloud-armory
service_account_key: ${{ secrets.GCP_KEY }}
export_default_credentials: true

- name: push image to registry
run: |
gcloud auth configure-docker -q
docker push gcr.io/cloud-armory/${{ steps.get_project_info.outputs.PROJECT_KEBAB }}:${{ steps.get_project_info.outputs.VERSION }}
40 changes: 40 additions & 0 deletions .github/workflows/updateDependencies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Update Dependencies

on:
repository_dispatch:
types: UpdateDependencies

jobs:
update_dependencies:
name: Update Dependencies
runs-on: ubuntu-latest
steps:
- name: echo event
run: |
echo "${{ toJson(github.event.client_payload) }}"
- name: checkout code
uses: actions/checkout@v2
with:
ref: ${{ github.event.client_payload.branchName }}
- name: update versions
if: github.event.client_payload.hasDependencyUpdates == true
run: |
find . -type f -name "*.gradle" -exec sed -i -e 's,"http://dl.bintray.com/spinnaker/spinnaker/","https://spinnaker-releases.bintray.com/jars",' {} \;
echo "${{ github.event.client_payload.newGradleProperties }}" > gradle.properties
- name: Create Pull Request
if: github.event.client_payload.hasDependencyUpdates == true
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.TOKEN }}
commit-message: "update dependencies to platform version ${{ github.event.client_payload.platformVersion }}"
branch: ${{ github.event.client_payload.platformVersion }}
branch-suffix: timestamp
title: "Update dependencies to platform version ${{ github.event.client_payload.platformVersion }}"
body: |
Event
```
${{ toJson(github.event.client_payload) }}
```
labels: |
updateDeps
autoMerge
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
build
.gradle
.idea
node_modules
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM alpine

COPY build/distributions/ /plugins
14 changes: 14 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
APACHE 2.0 LICENSE

Copyright 2019 Armory, Inc.

Licensed under the Apache License, Version 2.0 (the "License")
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
87 changes: 87 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
![CI](https://github.com/spinnaker-plugin-examples/pf4jStagePlugin/workflows/CI/badge.svg)

The [pf4jStagePlugin](https://github.com/spinnaker-plugin-examples/pf4jStagePlugin), also called the RandomWait plugin, creates a custom pipeline stage that waits a random number of seconds before signaling success.

This is for demo only and not meant to be used in a production environment.

# Version Compatibility

| Plugin | Spinnaker Platform |
|:----------- | :--------- |
| 1.0.x | 1.19.x |
| 1.1.x | 1.20.x |

# Usage

1) Run `./gradlew releaseBundle`
2) Put the `/build/distributions/<project>-<version>.zip` into the [configured plugins location for your service](https://pf4j.org/doc/packaging.html).
3) Configure the Spinnaker service. Put the following in the service yml to enable the plugin and configure the extension:

```
spinnaker:
extensibility:
plugins:
Armory.RandomWaitPlugin:
enabled: true
config:
defaultMaxWaitTime: 60
```

Or use the [examplePluginRepository](https://github.com/spinnaker-plugin-examples/examplePluginRepository) to avoid copying the plugin `.zip` artifact.

## Deployment on Spinnaker 1.20.6+

See the [Plugin Users Guide](https://spinnaker.io/guides/user/plugins/) and the [pf4jStagePlugin Deployment Example](https://spinnaker.io/guides/user/plugins/deploy-example/).

# Debugging

To debug the `random-wait-orca` server component inside a Spinnaker service (like Orca) using IntelliJ Idea follow these steps:

1) Run `./gradlew releaseBundle` in the plugin project.
2) Copy the generated `.plugin-ref` file under `build` in the plugin project submodule for the service to the `plugins` directory under root in the Spinnaker service that will use the plugin .
3) Link the plugin project to the service project in IntelliJ (from the service project use the `+` button in the Gradle tab and select the plugin build.gradle).
4) Configure the Spinnaker service the same way specified above.
5) Create a new IntelliJ run configuration for the service that has the VM option `-Dpf4j.mode=development` and does a `Build Project` before launch.
6) Debug away...

See the [Test a Pipeline Stage Plugin](https://spinnaker.io/guides/developer/plugin-creators/deck-plugin/) guide for a detailed walkthrough of setting up a plugin local testing environment on your workstation.

# Videos

* [Intro to Spinnaker Plugins](https://youtu.be/HtkXeC8a38Y), 2020 April Spinnaker Gardening Days
* [Plugins Training Workshop](https://youtu.be/oEHPvO88ROA), 2020 July Spinnaker Gardening Days
* [How to build a PLUGIN: Building the frontend for a Spinnaker-native custom stage](https://youtu.be/u9NVlG58NYo)
* [How to build a PLUGIN: Creating a Spinnaker-native custom stage](https://youtu.be/b7BmMY1kR10)
* [Backend Plugin Development](https://drive.google.com/open?id=1JPkXG5NnXowb1OElAFj2VjnpvUDA-Wyi)
* [How to build a PLUGIN: The build process for a Spinnaker plugin](https://youtu.be/-AIOXdgvNqs)
* [How to build a PLUGIN: Delivering a plugin to your Spinnaker environment](https://youtu.be/G2eyc9gzNS0)

# Architecture

The plugin consists of a `random-wait-orca` [Kotlin](https://kotlinlang.org/docs/reference/) server component and a `random-wait-deck` [React](https://reactjs.org/) UI component that uses the [rollup.js](https://rollupjs.org/guide/en/#plugins-overview) plugin library.

## `random-wait-orca`

This component implements the [StageDefinitionBuilder](https://github.com/spinnaker/orca/blob/master/orca-api/src/main/java/com/netflix/spinnaker/orca/api/pipeline/graph/StageDefinitionBuilder.java) PF4J extension point in Orca and consists of three classes in the `io.armory.plugin.state.wait.random` package:

* `RandomWaitContext.kt`: a data class that stores the `maxWaitTime` value
* `RandomWaitConfig.kt`: a data class with the `@PluginConfiguration` tag; key-value pairs in this class map to the plugin's configuration
* `RandomWaitPlugin.kt`: this is the plugin's main class; implements `StageDefinitionBuilder`

When adding a stage to a pipeline in the Spinnaker UI, the user can select this `Armory.RandomWaitPlugin` stage from the **Type** dropdown list. You enter a `maxWaitTime`, which is deserialized in `RandomWaitContext`.

Watch [How to build a PLUGIN: Creating a Spinnaker-native custom stage](https://youtu.be/b7BmMY1kR10) and read [code comments](https://github.com/spinnaker-plugin-examples/pf4jStagePlugin/tree/master/random-wait-orca/src/main/kotlin/io/armory/plugin/stage/wait/random) for more information.

## `random-wait-deck`

Prior to v1.1.4, this component used the [`rollup.js`](https://rollupjs.org/guide/en/#plugins-overview) plugin library to create a UI widget for Deck.

* `rollup.config.js`: configuration for building the JavaScript application
* `package.json`: defines dependencies
* `RandomWaitStage.tsx`: defines the custom pipeline stage; renders UI output
* `index.ts`: exports the name and custom stages

The code was refactored in v1.1.5 to use the new Deck UI SDK. `rollup.config.js`
now points to the config defined by the UI SDK. It's mostly not necessary to
define your own build config. This is also true of `tsconfig.json`. If you use
the UI SDK, you no longer define how your TypeScript should be compiled.
53 changes: 53 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
buildscript {
repositories {
mavenCentral()
}
}

plugins {
id("io.spinnaker.plugin.bundler").version("$spinnakerGradleVersion")
id("com.palantir.git-version").version("0.12.2")
id("com.diffplug.spotless").version("5.1.0")
}

repositories {
mavenCentral()
}

spinnakerBundle {
pluginId = "Armory.RandomWaitPlugin"
description = "An example of a PF4J-based plugin that provides a custom pipeline stage."
provider = "https://github.com/spinnaker-plugin-examples"
version = rootProject.version
}

version = normalizedVersion()

subprojects {
group = "io.armory.plugin.stage.wait.random"
version = rootProject.version

if (name != "random-wait-deck") {
apply plugin: "com.diffplug.spotless"
spotless {
kotlin {
ktlint().userData([
disabled_rules : "no-wildcard-imports",
indent_size : "2",
continuation_indent_size: "2",
])
}
}
}
}

String normalizedVersion() {
String fullVersion = gitVersion()
String normalized = fullVersion.split("-").first()
if (fullVersion.contains("dirty")) {
return "$normalized-SNAPSHOT"
} else {
return normalized
}
}

35 changes: 35 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
spinnakerRelease=master-20210212010018
org.gradle.parallel=true

spinnakerGradleVersion=8.10.0
pf4jVersion=3.2.0
korkVersion=7.99.1
orcaVersion=2.19.0-20210209140018
kotlinVersion=1.3.50



























Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 8246951

Please sign in to comment.