From f49d36a7768900a09f1e5283c33fb61d32feb50b Mon Sep 17 00:00:00 2001 From: Oliver Gould Date: Sun, 17 Mar 2024 00:05:52 +0000 Subject: [PATCH] ci: Update release workflow to be triggered via API Previously, we have triggered release workflows by pushing a tag to the repo. While this isn't a huge problem, it's sub-optimal for automation workflows, where can rely on the `gh` CLI, and it's a sub-optimal user interface compared to the GitHub Actions UI. This change updates the release workflow to be triggered by a workflow_dispatch event with a set of metadata that is used to drive the release process. These inputs can be specified when triggering the workflow. For example: :; gh workflow run release.yml -f version=v2.220.0 -f publish=true --- .github/workflows/release.yml | 108 ++++++++++++++++++++++------------ justfile | 3 +- 2 files changed, 71 insertions(+), 40 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5f88887c41..d41232839a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,12 +2,23 @@ name: Release on: pull_request: {} - push: - tags: - - "release/*" - -permissions: - contents: write + workflow_dispatch: + inputs: + version: + description: "Version in the form v1.2.3-prerelease+buildinfo." + required: true + tag-prefix: + description: "Tag prefix" + required: false + default: "release/" + profile: + description: "Build profile: debug or release." + required: false + default: "release" + publish: + description: "Publish the release?" + required: false + default: false env: CARGO_INCREMENTAL: 0 @@ -17,7 +28,7 @@ env: RUSTUP_MAX_RETRIES: 10 concurrency: - group: ${{ github.workflow }}-${{ github.head_ref }} + group: ${{ github.workflow }}-${{ github.head_ref }} cancel-in-progress: true jobs: @@ -26,44 +37,40 @@ jobs: runs-on: ubuntu-latest steps: - id: meta + env: + VERSION: ${{ inputs.version }} shell: bash run: | + set -euo pipefail shopt -s extglob - ref="${{ github.ref }}" - if [[ "$ref" == refs/tags/release/* ]]; then - ver="${ref##refs/tags/release/}" - # Semver-ish - if ! echo "$ver" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+)?(\+[0-9A-Za-z-]+)?$' ; then - echo "Invalid version: $ver" >&2 - exit 1 - fi - ( echo publish=true - echo version="${ver#v}" - echo archs='["amd64", "arm64", "arm"]' - ) >> "$GITHUB_OUTPUT" - else - sha="${{ github.sha }}" - ( echo version="0.0.0-test.${sha:0:7}" - echo archs='["amd64"]' - ) >> "$GITHUB_OUTPUT" + if [[ '${{ github.event_name }}' == "pull_request" ]]; then + echo version="0.0.0-test.${SHA:0:7}" + echo archs='["amd64"]' + exit 0 + fi >> "$GITHUB_OUTPUT" + if ! [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+)?(\+[0-9A-Za-z-]+)?$ ]]; then + echo "Invalid version: $VERSION" >&2 + exit 1 fi + ( echo version="${VERSION#v}" + echo archs='["amd64", "arm64", "arm"]' + ) >> "$GITHUB_OUTPUT" - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - if: steps.meta.outputs.publish != 'true' + if: github.event_name == 'pull_request' - id: changed - if: steps.meta.outputs.publish != 'true' + if: github.event_name == 'pull_request' uses: tj-actions/changed-files@77af4bed286740ef1a6387dc4e4e4dec39f96054 with: - # .github/workflows/release.yml files: | + .github/workflows/release.yml justfile Cargo.toml outputs: archs: ${{ steps.meta.outputs.archs }} - publish: ${{ steps.meta.outputs.publish == 'true' }} version: ${{ steps.meta.outputs.version }} - changed: ${{ steps.changed.outputs.any_changed == 'true' }} + package: ${{ github.event_name == 'workflow_dispatch' || steps.changed.outputs.any_changed == 'true' }} info: needs: meta @@ -73,14 +80,17 @@ jobs: - name: Info run: | echo 'github.repository_owner: ${{ github.repository_owner }}' - echo 'needs.meta.outputs.publish: ${{ needs.meta.outputs.publish }}' - echo 'needs.meta.outputs.publish: ${{ needs.meta.outputs.archs }}' + echo 'inputs.version: ${{ inputs.version }}' + echo 'inputs.tag-prefix: ${{ inputs.tag-prefix }}' + echo 'inputs.profile: ${{ inputs.profile }}' + echo 'inputs.publish: ${{ inputs.publish }}' + echo 'needs.meta.outputs.archs: ${{ needs.meta.outputs.archs }}' echo 'needs.meta.outputs.version: ${{ needs.meta.outputs.version }}' - echo 'needs.meta.outputs.changed: ${{ needs.meta.outputs.changed }}' + echo 'needs.meta.outputs.package: ${{ needs.meta.outputs.package }}' package: needs: meta - if: needs.meta.outputs.changed == 'true' || needs.meta.outputs.publish == 'true' + if: needs.meta.outputs.package == 'true' strategy: matrix: @@ -89,7 +99,7 @@ jobs: # If we're not actually building on a release tag, don't short-circuit on # errors. This helps us know whether a failure is platform-specific. - continue-on-error: ${{ needs.meta.outputs.publish != 'true' }} + continue-on-error: ${{ inputs.publish != 'true' }} runs-on: ubuntu-latest timeout-minutes: 40 container: docker://ghcr.io/linkerd/dev:v43-rust-musl @@ -97,12 +107,16 @@ jobs: LINKERD2_PROXY_VENDOR: ${{ github.repository_owner }} LINKERD2_PROXY_VERSION: ${{ needs.meta.outputs.version }} steps: + - name: Configure git + run: git config --global --add safe.directory "$PWD" # actions/runner#2033 - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - run: git config --global --add safe.directory "$PWD" # actions/runner#2033 + - uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 + with: + key: ${{ matrix.libc }} - run: just fetch - run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} rustup - - run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} profile=release build - - run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} profile=release package + - run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} profile=${{ inputs.profile }} build + - run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} profile=${{ inputs.profile }} package - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 with: name: ${{ matrix.arch }}-artifacts @@ -110,18 +124,34 @@ jobs: publish: needs: [meta, package] - if: needs.meta.outputs.changed == 'true' || needs.meta.outputs.publish == 'true' runs-on: ubuntu-latest timeout-minutes: 5 + permissions: + contents: write + env: + TAG: "${{ inputs.tag-prefix }}v${{ needs.meta.outputs.version }}" steps: + - name: Configure git + run: | + git config --global --add safe.directory "$PWD" # actions/runner#2033 + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + # Tag the release. + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - run: git tag -a -m "v${{ needs.meta.outputs.version }}" "$TAG" + # Fetch the artifacts. - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 with: path: artifacts - run: du -h artifacts/**/* - - if: needs.meta.outputs.publish == 'true' + # Publish the release. + - if: inputs.publish == 'true' + run: git push origin "$TAG" + - if: inputs.publish == 'true' uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 with: name: v${{ needs.meta.outputs.version }} + tag_name: ${{ env.TAG }} files: artifacts/**/* generate_release_notes: true diff --git a/justfile b/justfile index 592bb5a531..2dc928d6ae 100644 --- a/justfile +++ b/justfile @@ -116,7 +116,8 @@ test-dir dir *flags: cd {{ dir }} && {{ _cargo }} test --frozen {{ _features }} {{ flags }} # Build the proxy -build: _build checksec _strip +# XXX(ver) checksec doesn't work when profile=debug, so skip it. +build: _build _strip # Build the proxy without stripping debug symbols build-debug: _build