-
Notifications
You must be signed in to change notification settings - Fork 3
ci: automate action releases #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
939173f
ci: automate action releases
chaptersix f33d7e4
fix: make release retries safe
chaptersix 4d13a4b
refactor: share action verification workflows
chaptersix d206801
fix: avoid shell interpolation in verification
chaptersix 4c0af99
ci: lint action source
chaptersix File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| name: Release | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| version: | ||
| description: Immutable release tag (for example, v0.2.0) | ||
| required: true | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| concurrency: | ||
| group: release | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| require-main: | ||
| name: Require main | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Reject a non-main ref | ||
| if: github.ref != 'refs/heads/main' | ||
| shell: bash | ||
| run: | | ||
| echo "Releases must be dispatched from main, not $GITHUB_REF" >&2 | ||
| exit 1 | ||
|
|
||
| verify: | ||
| needs: require-main | ||
| uses: ./.github/workflows/verify.yml | ||
|
|
||
| release: | ||
| name: Publish release | ||
| needs: verify | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 | ||
| with: | ||
| node-version: 24 | ||
| package-manager-cache: false | ||
|
|
||
| - name: Verify release version | ||
| id: release | ||
| env: | ||
| VERSION: ${{ inputs.version }} | ||
| shell: bash | ||
| run: | | ||
| if [[ ! "$VERSION" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then | ||
| echo "version must be a stable semantic tag such as v0.2.0" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| package_version="v$(node --print \"require('./package.json').version\")" | ||
| if [[ "$VERSION" != "$package_version" ]]; then | ||
| echo "version $VERSION does not match package.json ($package_version)" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "major_tag=v${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Verify any existing release tag | ||
| id: tag | ||
| env: | ||
| VERSION: ${{ inputs.version }} | ||
| shell: bash | ||
| run: | | ||
| git fetch --tags --force origin | ||
| if git rev-parse --verify --quiet "refs/tags/$VERSION^{}" >/dev/null; then | ||
| tag_commit="$(git rev-parse "refs/tags/$VERSION^{}")" | ||
| if [[ "$tag_commit" != "$GITHUB_SHA" ]]; then | ||
| echo "Release tag $VERSION already exists at $tag_commit, not $GITHUB_SHA" >&2 | ||
| exit 1 | ||
| fi | ||
| echo "exists=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "exists=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| - name: Create immutable release tag and GitHub Release | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| TAG_EXISTS: ${{ steps.tag.outputs.exists }} | ||
| VERSION: ${{ inputs.version }} | ||
| shell: bash | ||
| run: | | ||
| git config --local user.name 'Temporal Data' | ||
| git config --local user.email 'commander-data@temporal.io' | ||
| if [[ "$TAG_EXISTS" != "true" ]]; then | ||
| git tag -a "$VERSION" "$GITHUB_SHA" -m "Release $VERSION" | ||
| git push origin "refs/tags/$VERSION" | ||
| fi | ||
|
|
||
| if ! gh release view "$VERSION" >/dev/null 2>&1; then | ||
| gh release create "$VERSION" --title "$VERSION" --generate-notes | ||
| fi | ||
|
|
||
| - name: Advance the compatible major tag | ||
| env: | ||
| MAJOR_TAG: ${{ steps.release.outputs.major_tag }} | ||
| VERSION: ${{ inputs.version }} | ||
| shell: bash | ||
| run: | | ||
| git tag -fa "$MAJOR_TAG" "$VERSION" -m "Update $MAJOR_TAG to $VERSION" | ||
| git push origin "refs/tags/$MAJOR_TAG" --force | ||
|
|
||
| - name: Verify published references | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| MAJOR_TAG: ${{ steps.release.outputs.major_tag }} | ||
| VERSION: ${{ inputs.version }} | ||
| shell: bash | ||
| run: | | ||
| git ls-remote --tags origin "refs/tags/$VERSION" "refs/tags/$VERSION^{}" \ | ||
| "refs/tags/$MAJOR_TAG" "refs/tags/$MAJOR_TAG^{}" | ||
| gh release view "$VERSION" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| name: Verify action | ||
|
|
||
| on: | ||
| workflow_call: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| bundle: | ||
| name: Verify generated bundle | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | ||
|
|
||
| - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 | ||
| with: | ||
| node-version: 24 | ||
| package-manager-cache: false | ||
|
|
||
| - run: npm ci | ||
| - run: npm run build | ||
| - run: git diff --check | ||
| - name: Verify generated bundle is committed | ||
| shell: bash | ||
| run: | | ||
| if ! git diff --quiet -- dist/setup-temporal; then | ||
| echo "::error file=dist/setup-temporal::The generated action bundle is stale. Run 'npm ci' and 'npm run build', then commit the changes under dist/setup-temporal/." >&2 | ||
| git diff -- dist/setup-temporal | ||
| exit 1 | ||
| fi | ||
|
|
||
| quality: | ||
| name: Lint and format | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | ||
|
|
||
| - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 | ||
| with: | ||
| node-version: 24 | ||
| package-manager-cache: false | ||
|
|
||
| - run: npm ci | ||
| - run: npm run lint | ||
| - run: npm run format:check | ||
|
|
||
| test: | ||
| strategy: | ||
| fail-fast: true | ||
| matrix: | ||
| os: [ubuntu-latest, macos-latest, windows-latest] | ||
| runs-on: ${{ matrix.os }} | ||
| steps: | ||
| - name: Print build information | ||
| env: | ||
| HEAD_REF: ${{ github.head_ref }} | ||
| REF: ${{ github.ref }} | ||
| OS: ${{ matrix.os }} | ||
| shell: bash | ||
| run: 'echo "head_ref: $HEAD_REF, ref: $REF, os: $OS"' | ||
|
|
||
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | ||
|
|
||
| - name: Run temporalio/setup-temporal | ||
| uses: ./ | ||
|
|
||
| - name: Verify setup | ||
| shell: bash | ||
| run: temporal -v |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Releasing `setup-temporal` | ||
|
|
||
| This repository is a JavaScript GitHub Action. The executable that GitHub runs | ||
| is checked in under `dist/setup-temporal`, so every source change that affects | ||
| the action must be built and committed before it is released. | ||
|
|
||
| ## Versioning and tags | ||
|
|
||
| Use semantic versioning and create an immutable, annotated tag for every | ||
| release, for example `v0.2.0`. | ||
|
|
||
| Consumers can choose either form: | ||
|
|
||
| ```yaml | ||
| # Receives compatible v0 updates. | ||
| uses: temporalio/setup-temporal@v0 | ||
|
|
||
| # Stays on this exact release. | ||
| uses: temporalio/setup-temporal@v0.2.0 | ||
| ``` | ||
|
|
||
| `v0` is the moving major-version tag. Move it only after publishing a new | ||
| backwards-compatible `v0.x.y` release. Do not move it for a breaking change; | ||
| publish that release under a new major tag (such as `v1`) instead. | ||
|
|
||
| ## Release procedure | ||
|
|
||
| 1. Prepare and merge a release PR to `main`. Set `package.json` to the next | ||
| version (without the `v` prefix), regenerate the committed bundle, and wait | ||
| for the Validate workflow to pass. | ||
|
|
||
| ```bash | ||
| npm ci | ||
| npm run build | ||
| ``` | ||
|
|
||
| Commit any change under `dist/setup-temporal` with the source change. The | ||
| action executes that checked-in bundle, not the TypeScript source. | ||
|
|
||
| If the **Verify generated bundle is committed** PR check fails, run the two | ||
| commands above from the repository root, review the changes under | ||
| `dist/setup-temporal`, and commit them. If `npm run build` itself fails, fix | ||
| the reported source or dependency compatibility error before regenerating | ||
| the bundle. | ||
|
|
||
| 2. In GitHub, open **Actions** → **Release** → **Run workflow**. Select | ||
| `main`, enter the corresponding semantic release tag (for example, | ||
| `v0.2.0`), and run it. | ||
|
|
||
| 3. The workflow runs the action on Linux, macOS, and Windows; rebuilds and | ||
| checks the committed bundle; verifies the requested tag matches | ||
| `package.json`; creates the immutable GitHub Release; and then advances the | ||
| compatible major tag (`v0` for `v0.2.0`). | ||
|
|
||
| The workflow only runs from `main`, accepts stable `vMAJOR.MINOR.PATCH` tags, | ||
| and refuses a release tag that points to a different commit. A retry safely | ||
| resumes when the immutable tag already points to the dispatched commit. It has | ||
| `contents: write` permission because it creates tags and the GitHub Release; | ||
| the major tag is the only tag it force-updates. | ||
|
|
||
| ## Rollback | ||
|
|
||
| Do not delete or reuse the immutable release tag. If a bad compatible release | ||
| was made, publish a new patch release with the fix and move `v0` forward to it. | ||
| If `v0` was accidentally moved, repoint only `v0` to the last known-good | ||
| immutable tag and communicate that correction to consumers. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a draft release already exists for
$VERSION,gh release viewsucceeds, so this branch skips creation and the workflow advances the compatible major tag and finishes successfully even though no published immutable release exists. I checkedgh2.96.0:gh release view --helpexposes theisDraftfield,gh release create --helpstates that immutability applies only after publication, andgh release edit --helpdocuments--draft=falsefor publishing an existing draft. Inspect the existing release state and publish or reject drafts before moving the major tag.Useful? React with 👍 / 👎.