From fb3117000997ec1e7eb0d0066ce5aaf1e67d7605 Mon Sep 17 00:00:00 2001 From: "maxim.yanchuk" Date: Tue, 26 Dec 2023 11:53:21 +0300 Subject: [PATCH] LP-2725: plugin ci template & actions --- .gitea/actions/file-sign/action.yml | 36 +++++ .gitea/actions/plugin/build/action.yml | 50 +++++++ .gitea/actions/plugin/json/action.yml | 49 +++++++ .../loop-plugin-with-marketplace-template.yml | 131 ++++++++++++++++++ 4 files changed, 266 insertions(+) create mode 100644 .gitea/actions/file-sign/action.yml create mode 100644 .gitea/actions/plugin/build/action.yml create mode 100644 .gitea/actions/plugin/json/action.yml create mode 100644 .gitea/workflows/loop-plugin-with-marketplace-template.yml diff --git a/.gitea/actions/file-sign/action.yml b/.gitea/actions/file-sign/action.yml new file mode 100644 index 0000000..b3f4995 --- /dev/null +++ b/.gitea/actions/file-sign/action.yml @@ -0,0 +1,36 @@ +name: sign +description: Sign file + +inputs: + private_key: + required: true + description: 'Private key' + private_key_id: + required: true + description: 'Private key id' + private_key_passphrase: + required: true + description: 'Private key passphrase' + filepath: + required: true + description: 'Absolute or relative for workdir file path for sign' + +runs: + using: composite + steps: + - name: ci/protect-sensitive + shell: bash + run: | + echo ::add-mask::$INPUT_PRIVATE_KEY + echo ::add-mask::$INPUT_PRIVATE_KEY_ID + echo ::add-mask::$INPUT_PRIVATE_KEY_PASSPHRASE + + - name: ci/import-private-key + uses: crazy-max/ghaction-import-gpg@v6 + with: + gpg_private_key: ${{ inputs.private_key }} + passphrase: ${{ inputs.private_key_passphrase }} + + - name: ci/sign + shell: bash + run: gpg -u ${{ inputs.private_key_id }} --verbose --personal-digest-preferences SHA256 --detach-sign ${{ inputs.filepath }} diff --git a/.gitea/actions/plugin/build/action.yml b/.gitea/actions/plugin/build/action.yml new file mode 100644 index 0000000..42f0f85 --- /dev/null +++ b/.gitea/actions/plugin/build/action.yml @@ -0,0 +1,50 @@ +name: build +description: Build plugin via yarn & make + +inputs: + go_version: + required: false + description: 'GO version' + node_version: + required: false + description: 'Node.js version' + +runs: + using: composite + steps: + - name: ci/setup-go + uses: actions/setup-go@v4 + if: ${{ inputs.go_version }} + with: + go-version: "${{ inputs.go_version }}" + cache-dependency-path: | + go.sum + server/go.sum + + - name: ci/setup-node + uses: actions/setup-node@v4 + if: ${{ inputs.node_version }} + with: + node-version: "${{ inputs.node_version }}" +# TODO cache yarn +# cache: "yarn" +# cache-dependency-path: yarn.lock + +# TODO tests +# - name: ci/plugin-test + + - name: ci/install-deps + if: ${{ inputs.node_version }} + shell: bash + run: | + echo "::group::yarn" + cd webapp + yarn install + echo "::endgroup::" + + - name: ci/plugin-build + shell: bash + run: | + echo "::group::dist" + make dist + echo "::endgroup::" diff --git a/.gitea/actions/plugin/json/action.yml b/.gitea/actions/plugin/json/action.yml new file mode 100644 index 0000000..08a86be --- /dev/null +++ b/.gitea/actions/plugin/json/action.yml @@ -0,0 +1,49 @@ +name: json +description: Build plugin json for marketplace + +inputs: + plugin_id: + required: true + description: 'Plugin id' + plugin_version: + required: true + description: 'Plugin version' + enterprise: + required: true + description: 'Is plugin enterprise' + beta: + required: true + description: 'Is plugin beta' + experimental: + required: true + description: 'Is plugin experimental' + artifacts_url: + required: true + description: 'Artifacts URL' + artifacts_repository: + required: true + description: 'Artifacts repository' + +runs: + using: composite + steps: + - name: ci/install-marketplace + shell: bash + run: | + git clone --branch production https://github.com/mattermost/mattermost-marketplace.git ./marketplace + git -C ./marketplace reset --hard 3d2177a488d01887de993364c36afc62cd7ab416 + echo [] > ./marketplace/plugins.json + + - name: ci/add-json + shell: bash + run: | + cd marketplace + args="" + if [ "${{ inputs.enterprise }}" = true ]; then args+=" --enterprise"; fi + if [ "${{ inputs.beta }}" = true ]; then args+=" --beta"; fi + if [ "${{ inputs.experimental }}" = true ]; then args+=" --experimental"; fi + go run ./cmd/generator/ add ${{ inputs.plugin_id }} ${{ inputs.plugin_version }} --official --remote-plugin-store=${{ inputs.artifacts_url }}/repository/${{ inputs.artifacts_repository }}/plugins/${{ inputs.plugin_id }}/${{ inputs.plugin_version }} $args + + - name: ci/extract-json + shell: bash + run: jq '.[0] | .author_type = "loop"' ./marketplace/plugins.json >> ./dist/${{ inputs.plugin_id }}-${{ inputs.plugin_version }}.tar.gz.json diff --git a/.gitea/workflows/loop-plugin-with-marketplace-template.yml b/.gitea/workflows/loop-plugin-with-marketplace-template.yml new file mode 100644 index 0000000..04c37ac --- /dev/null +++ b/.gitea/workflows/loop-plugin-with-marketplace-template.yml @@ -0,0 +1,131 @@ +name: Build and sign plugin with marketplace json formation +on: + workflow_call: + inputs: + go_version: + required: false + description: 'GO version' + node_version: + required: false + description: 'Node.js version' + vault_secrets_base_path: + required: true + description: 'Базовый путь для секретов проекта в vault' + artifacts_url: + required: true + description: 'Artifacts URL' + artifacts_repository: + required: true + description: 'Artifacts repository' + secrets: + VAULT_ROLE_ID: + required: true + VAULT_SECRET_ID: + required: true + +jobs: + release: + name: release + runs-on: ubuntu-22.04 + steps: + - name: ci/checkout-repo + uses: actions/checkout@v3 + + - id: publish-secrets + name: ci/publish-secrets + uses: https://github.com/hashicorp/vault-action@v2 + with: + url: https://vault.wilix.dev + method: approle + roleId: ${{ secrets.VAULT_ROLE_ID }} + secretId: ${{ secrets.VAULT_SECRET_ID }} + secrets: | + ${{ inputs.vault_secrets_base_path }} ARTIFACTS_USERNAME ; + ${{ inputs.vault_secrets_base_path }} ARTIFACTS_PASSWORD ; + + - id: key + name: ci/key + uses: https://github.com/hashicorp/vault-action@v2 + with: + url: https://vault.wilix.dev + method: approle + roleId: ${{ secrets.VAULT_ROLE_ID }} + secretId: ${{ secrets.VAULT_SECRET_ID }} + secrets: | + ${{ inputs.vault_secrets_base_path }} SIGN_PRIVATE_KEY_EXPORTED ; + ${{ inputs.vault_secrets_base_path }} SIGN_PRIVATE_KEY_ID ; + ${{ inputs.vault_secrets_base_path }} SIGN_PRIVATE_KEY_PASSPHRASE ; + + - id: plugin-meta + name: ci/plugin-meta + shell: bash + run: | + apt-get update + apt-get install -y jq + echo "PLUGIN=$(jq -r '.id + "-" + .version + ".tar.gz"' plugin.json)" >> "$GITHUB_OUTPUT" + echo "PLUGIN_ID=$(jq -r '.id' plugin.json)" >> "$GITHUB_OUTPUT" + echo "PLUGIN_VERSION=$(jq -r '.version' plugin.json)" >> "$GITHUB_OUTPUT" + echo "ENTERPRISE=$(jq -r '.props.enterprise == true' plugin.json)" >> "$GITHUB_OUTPUT" + echo "BETA=$(jq -r '.version | contains("SNAPSHOT")' plugin.json)" >> "$GITHUB_OUTPUT" + echo "EXPERIMENTAL=$(jq -r '.props.experimental == true' plugin.json)" >> "$GITHUB_OUTPUT" + + - name: ci/plugin-build + uses: https://git.wilix.dev/wilix-infra/actions/.gitea/actions/plugin/build@master + with: + go_version: ${{ inputs.go_version }} + node_version: ${{ inputs.node_version }} + + - name: ci/plugin-sign + uses: https://git.wilix.dev/wilix-infra/actions/.gitea/actions/file-sign@master + with: + private_key: ${{ steps.key.outputs.SIGN_PRIVATE_KEY_EXPORTED }} + private_key_id: ${{ steps.key.outputs.SIGN_PRIVATE_KEY_ID }} + private_key_passphrase: ${{ steps.key.outputs.SIGN_PRIVATE_KEY_PASSPHRASE }} + filepath: ${{ gitea.workspace }}/dist/${{ steps.plugin-meta.outputs.PLUGIN }} + + - name: ci/push-plugin + uses: sonatype-nexus-community/nexus-repo-github-action@master + with: + serverUrl: ${{ inputs.artifacts_url }} + username: ${{ steps.publish-secrets.outputs.ARTIFACTS_USERNAME }} + password: ${{ steps.publish-secrets.outputs.ARTIFACTS_PASSWORD }} + format: raw + repository: ${{ inputs.artifacts_repository }} + coordinates: directory=plugins/${{ steps.plugin-meta.outputs.PLUGIN_ID }}/${{ steps.plugin-meta.outputs.PLUGIN_VERSION }} + assets: filename=${{ steps.plugin-meta.outputs.PLUGIN }} + filename: dist/${{ steps.plugin-meta.outputs.PLUGIN }} + + - name: ci/push-plugin-sign + uses: sonatype-nexus-community/nexus-repo-github-action@master + with: + serverUrl: ${{ inputs.artifacts_url }} + username: ${{ steps.publish-secrets.outputs.ARTIFACTS_USERNAME }} + password: ${{ steps.publish-secrets.outputs.ARTIFACTS_PASSWORD }} + format: raw + repository: ${{ inputs.artifacts_repository }} + coordinates: directory=plugins/${{ steps.plugin-meta.outputs.PLUGIN_ID }}/${{ steps.plugin-meta.outputs.PLUGIN_VERSION }} + assets: filename=${{ steps.plugin-meta.outputs.PLUGIN }}.sig + filename: dist/${{ steps.plugin-meta.outputs.PLUGIN }}.sig + + - name: ci/plugin-json + uses: https://git.wilix.dev/wilix-infra/actions/.gitea/actions/plugin/json@master + with: + plugin_id: ${{ steps.plugin-meta.outputs.PLUGIN_ID }} + plugin_version: ${{ steps.plugin-meta.outputs.PLUGIN_VERSION }} + enterprise: ${{ steps.plugin-meta.outputs.ENTERPRISE }} + beta: ${{ steps.plugin-meta.outputs.BETA }} + experimental: ${{ steps.plugin-meta.outputs.EXPERIMENTAL }} + artifacts_url: ${{ inputs.artifacts_url }} + artifacts_repository: ${{ inputs.artifacts_repository }} + + - name: ci/push-plugin-json + uses: sonatype-nexus-community/nexus-repo-github-action@master + with: + serverUrl: ${{ inputs.artifacts_url }} + username: ${{ steps.publish-secrets.outputs.ARTIFACTS_USERNAME }} + password: ${{ steps.publish-secrets.outputs.ARTIFACTS_PASSWORD }} + format: raw + repository: ${{ inputs.artifacts_repository }} + coordinates: directory=plugins/${{ steps.plugin-meta.outputs.PLUGIN_ID }}/${{ steps.plugin-meta.outputs.PLUGIN_VERSION }} + assets: filename=${{ steps.plugin-meta.outputs.PLUGIN }}.json + filename: dist/${{ steps.plugin-meta.outputs.PLUGIN }}.json