From 0ab88c24b40f8c5786a5ec7bc68b25f18ee58712 Mon Sep 17 00:00:00 2001 From: Brad White Date: Sat, 21 Mar 2026 11:55:57 +1000 Subject: [PATCH 1/9] downgrade version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b98053..55c5fd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "elastic-github-actions", - "version": "3.0.0", + "version": "2.1.1", "description": "Elastic Organization GitHub Actions", "repository": { "type": "git", From a211e3d73d7b9bacdc6cafed169d6cf920ac9efe Mon Sep 17 00:00:00 2001 From: Brad White Date: Wed, 25 Mar 2026 12:13:51 +1000 Subject: [PATCH 2/9] package json version based release flow --- .github/release.yml | 21 ++++++ .github/workflows/release.yml | 119 ++++++++++++++++++++++------------ CHANGELOG.md | 5 ++ README.md | 16 ++++- 4 files changed, 118 insertions(+), 43 deletions(-) create mode 100644 .github/release.yml create mode 100644 CHANGELOG.md diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..b8e5218 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,21 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-release-config.json +changelog: + exclude: + labels: + - ignore-for-release + categories: + - title: Breaking Changes + labels: + - breaking-change + - title: Enhancements + labels: + - enhancement + - title: Bug Fixes + labels: + - bug + - title: Dependencies + labels: + - dependencies + - title: Other Changes + labels: + - '*' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b440646..8349dab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,12 +1,11 @@ -name: Release +name: Publish Release on: - workflow_dispatch: - inputs: - version: - description: Semver tag to release, for example v1.2.3 - required: true - type: string + push: + branches: + - master + paths: + - 'package.json' concurrency: group: release @@ -16,23 +15,83 @@ permissions: contents: read jobs: + prepare: + runs-on: ubuntu-latest + outputs: + should_release: ${{ steps.version.outputs.should_release }} + tag: ${{ steps.version.outputs.tag }} + version: ${{ steps.version.outputs.version }} + major_tag: ${{ steps.version.outputs.major_tag }} + previous_tag: ${{ steps.version.outputs.previous_tag }} + + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + ref: ${{ github.sha }} + + - name: Resolve release version + id: version + run: | + VERSION="$(node --print "require('./package.json').version")" + + if ! printf '%s' "${VERSION}" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "package.json version must use x.y.z semver; received ${VERSION}." + exit 1 + fi + + TAG="v${VERSION}" + MAJOR_TAG="${TAG%%.*}" + PREVIOUS_TAG="$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | sed -n '1p')" + + echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" + echo "tag=${TAG}" >> "${GITHUB_OUTPUT}" + echo "major_tag=${MAJOR_TAG}" >> "${GITHUB_OUTPUT}" + echo "previous_tag=${PREVIOUS_TAG}" >> "${GITHUB_OUTPUT}" + + if git rev-parse "${TAG}" >/dev/null 2>&1; then + echo 'Release tag already exists. Skipping release.' + echo "should_release=false" >> "${GITHUB_OUTPUT}" + exit 0 + fi + + if [ -z "${PREVIOUS_TAG}" ]; then + echo 'Expected an existing previous release tag.' + exit 1 + fi + + PREVIOUS_VERSION="${PREVIOUS_TAG#v}" + + if [ "$(printf '%s\n%s\n' "${PREVIOUS_VERSION}" "${VERSION}" | sort -V | sed -n '$p')" != "${VERSION}" ]; then + echo "package.json version ${VERSION} must be greater than the latest release tag ${PREVIOUS_TAG}." + exit 1 + fi + + echo "should_release=true" >> "${GITHUB_OUTPUT}" + test: + if: ${{ needs.prepare.outputs.should_release == 'true' }} + needs: prepare uses: ./.github/workflows/test.yml with: - ref: master + ref: ${{ github.sha }} permissions: contents: read build: + if: ${{ needs.prepare.outputs.should_release == 'true' }} + needs: prepare uses: ./.github/workflows/build.yml with: - ref: master + ref: ${{ github.sha }} verify_dist: true permissions: contents: read release: - needs: [test, build] + if: ${{ needs.prepare.outputs.should_release == 'true' }} + needs: [prepare, test, build] runs-on: ubuntu-latest permissions: contents: write @@ -46,50 +105,28 @@ jobs: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - ref: master fetch-depth: 0 - - - name: Validate release input - env: - VERSION: ${{ inputs.version }} - run: | - if ! printf '%s' "${VERSION}" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$'; then - echo 'Version must use semver and start with v, for example v1.2.3.' - exit 1 - fi - - if git rev-parse "${VERSION}" >/dev/null 2>&1; then - echo "Tag ${VERSION} already exists." - exit 1 - fi + ref: ${{ github.sha }} - name: Create and push release tag env: - VERSION: ${{ inputs.version }} + TAG: ${{ needs.prepare.outputs.tag }} run: | - PREVIOUS_TAG="$(git describe --tags --abbrev=0 --match 'v[0-9]*.[0-9]*.[0-9]*' 2>/dev/null || true)" - echo "PREVIOUS_TAG=${PREVIOUS_TAG}" >> "${GITHUB_ENV}" - - git tag -a "${VERSION}" -m "Release ${VERSION}" - git push origin "refs/tags/${VERSION}" + git tag -a "${TAG}" -m "Release ${TAG}" "${GITHUB_SHA}" + git push origin "refs/tags/${TAG}" - name: Create GitHub release env: - VERSION: ${{ inputs.version }} GH_TOKEN: ${{ github.token }} + PREVIOUS_TAG: ${{ needs.prepare.outputs.previous_tag }} + TAG: ${{ needs.prepare.outputs.tag }} run: | - if [ -n "${PREVIOUS_TAG}" ]; then - gh release create "${VERSION}" --verify-tag --generate-notes --notes-start-tag "${PREVIOUS_TAG}" - else - gh release create "${VERSION}" --verify-tag --generate-notes - fi + gh release create "${TAG}" --verify-tag --generate-notes --notes-start-tag "${PREVIOUS_TAG}" - name: Update floating major tag env: - VERSION: ${{ inputs.version }} + MAJOR_TAG: ${{ needs.prepare.outputs.major_tag }} + RELEASE_SHA: ${{ github.sha }} run: | - MAJOR_TAG="${VERSION%%.*}" - RELEASE_SHA="$(git rev-parse HEAD)" - git tag -fa "${MAJOR_TAG}" -m "Release ${MAJOR_TAG}" "${RELEASE_SHA}" git push origin "refs/tags/${MAJOR_TAG}" --force diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..744f25b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +Release notes are published on the GitHub releases page: + + diff --git a/README.md b/README.md index a9c99cc..e55fa11 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,18 @@ updates must include an updated `pnpm-lock.yaml`. The build treats any **top-level directory** that contains an `action.yml` as an action and builds it with `@vercel/ncc`. `src/index.ts` is the required entrypoint. -### Release tags and floating majors +### Release tags, changelog, and floating majors -Releases are created via the `Release` workflow with a `version` like `v3.0.0`. In addition to creating the `vX.Y.Z` tag and GitHub release, it **force-updates** the floating major tag (for example `v3`). +The root [`package.json`](package.json) version is the release source of truth for this repository. + +To prepare a release: + +1. Open a pull request that bumps the root `package.json` `version` field. +2. Merge the pull request to `master`. + +After merge, the release workflow: + +- reads the merged package version and creates the matching `vX.Y.Z` tag +- generates release notes automatically with GitHub +- uses [`.github/release.yml`](.github/release.yml) labels and categories to section the release page +- force-updates the floating major tag (for example `v3`) From 5df8176fb82fe619f1f4f548c4579803301591b8 Mon Sep 17 00:00:00 2001 From: Brad White Date: Wed, 25 Mar 2026 12:15:47 +1000 Subject: [PATCH 3/9] rename file --- .github/workflows/{release.yml => publish-release.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{release.yml => publish-release.yml} (100%) diff --git a/.github/workflows/release.yml b/.github/workflows/publish-release.yml similarity index 100% rename from .github/workflows/release.yml rename to .github/workflows/publish-release.yml From 7989b4d8d020039015f6100e301ab605bac22495 Mon Sep 17 00:00:00 2001 From: Brad White Date: Thu, 26 Mar 2026 10:46:46 +1000 Subject: [PATCH 4/9] add setup node --- .github/workflows/publish-release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 8349dab..8eb986c 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -31,6 +31,11 @@ jobs: fetch-depth: 0 ref: ${{ github.sha }} + - name: Setup Node.js + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version: 24.14.0 + - name: Resolve release version id: version run: | From 2e1ccd53dbd92b850f2e5225e98effd518d451d5 Mon Sep 17 00:00:00 2001 From: Brad White Date: Thu, 26 Mar 2026 14:38:39 +1000 Subject: [PATCH 5/9] auto update dist in release prs --- .github/workflows/build.yml | 2 +- .github/workflows/publish-release.yml | 1 + .github/workflows/update-dist.yml | 58 +++++++++++++++++++++++---- README.md | 9 +++-- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d7b0687..888071d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,5 +58,5 @@ jobs: run: pnpm build - name: Verify committed build output - if: ${{ inputs.verify_dist }} + if: ${{ inputs.verify_dist || (github.event_name == 'pull_request' && startsWith(github.head_ref, 'release/')) }} run: git diff --exit-code diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 8eb986c..fb7d016 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -16,6 +16,7 @@ permissions: jobs: prepare: + if: github.event.repository.fork == false runs-on: ubuntu-latest outputs: should_release: ${{ steps.version.outputs.should_release }} diff --git a/.github/workflows/update-dist.yml b/.github/workflows/update-dist.yml index 33d8a38..c339c6a 100644 --- a/.github/workflows/update-dist.yml +++ b/.github/workflows/update-dist.yml @@ -6,9 +6,19 @@ on: - master paths-ignore: - 'project-assigner/**' + pull_request: + branches: + - master + paths: + - 'package.json' + types: + - opened + - synchronize + - reopened + - ready_for_review concurrency: - group: update-dist-${{ github.ref }} + group: update-dist-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true permissions: @@ -16,14 +26,24 @@ permissions: jobs: update-dist: - if: github.actor != 'github-actions[bot]' + if: >- + ${{ + github.actor != 'github-actions[bot]' && + github.event.repository.fork == false && + ( + github.event_name == 'push' || + ( + startsWith(github.head_ref, 'release/') && + contains(fromJSON('["MEMBER"]'), github.event.pull_request.author_association) + ) + ) + }} runs-on: ubuntu-latest - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - ref: master + ref: ${{ github.event_name == 'pull_request' && github.head_ref || 'master' }} fetch-depth: 0 - name: Setup pnpm @@ -45,11 +65,30 @@ jobs: - name: Commit updated dist output env: - GIT_AUTHOR_NAME: github-actions[bot] + BASE_REF: ${{ github.event.pull_request.base.ref || '' }} + HEAD_REF: ${{ github.head_ref || '' }} + EVENT_NAME: ${{ github.event_name }} GIT_AUTHOR_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com - GIT_COMMITTER_NAME: github-actions[bot] + GIT_AUTHOR_NAME: github-actions[bot] GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com + GIT_COMMITTER_NAME: github-actions[bot] run: | + read_package_version_from_ref() { + git show "$1:package.json" | node --print "JSON.parse(require('node:fs').readFileSync(0, 'utf8')).version" + } + + if [ "${EVENT_NAME}" = 'pull_request' ]; then + git fetch origin "${BASE_REF}" + + VERSION="$(read_package_version_from_ref 'HEAD')" + BASE_VERSION="$(read_package_version_from_ref "origin/${BASE_REF}")" + + if [ "${VERSION}" = "${BASE_VERSION}" ]; then + echo "Pull request does not bump package.json version. Skipping dist update." + exit 0 + fi + fi + if git diff --quiet; then echo "No dist updates to commit." exit 0 @@ -65,4 +104,9 @@ jobs: git diff --name-only -z | xargs -0 git add -- git commit -m "build: update dist for ${SOURCE_SHA}" - git push origin HEAD:master + + if [ "${EVENT_NAME}" = 'pull_request' ]; then + git push origin "HEAD:${HEAD_REF}" + else + git push origin HEAD:master + fi diff --git a/README.md b/README.md index e55fa11..820ee80 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,8 @@ directly from the repository ref they pin to. In this repository, `dist/` is tre artifact: - Pull requests are reviewed as source changes and must build successfully. +- Trusted same-repo `release/**` pull requests that bump the root `package.json` version auto-update + committed `dist/` output on each push. - `master` auto-updates committed `dist/` output after merges. - Releases rebuild and fail if a fresh build would change committed output, so release tags always point to commits with up-to-date `dist/`. @@ -118,14 +120,15 @@ updates must include an updated `pnpm-lock.yaml`. The build treats any **top-level directory** that contains an `action.yml` as an action and builds it with `@vercel/ncc`. `src/index.ts` is the required entrypoint. -### Release tags, changelog, and floating majors +### Release tags and floating majors The root [`package.json`](package.json) version is the release source of truth for this repository. To prepare a release: -1. Open a pull request that bumps the root `package.json` `version` field. -2. Merge the pull request to `master`. +1. Open a same-repo pull request with a branch in the form of `release/**` that bumps the root `package.json` `version` field. +2. Let CI auto-update committed `dist/` output on the release pull request as you push changes. +3. Merge the pull request to `master`. After merge, the release workflow: From c54a74e9406446bd352eaf0c720333baa9d2a690 Mon Sep 17 00:00:00 2001 From: Brad White Date: Wed, 25 Mar 2026 22:49:26 -0600 Subject: [PATCH 6/9] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/update-dist.yml | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 888071d..27cc814 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,5 +58,5 @@ jobs: run: pnpm build - name: Verify committed build output - if: ${{ inputs.verify_dist || (github.event_name == 'pull_request' && startsWith(github.head_ref, 'release/')) }} + if: ${{ inputs.verify_dist || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.head_ref, 'release/')) }} run: git diff --exit-code diff --git a/.github/workflows/update-dist.yml b/.github/workflows/update-dist.yml index c339c6a..922d0c4 100644 --- a/.github/workflows/update-dist.yml +++ b/.github/workflows/update-dist.yml @@ -29,10 +29,14 @@ jobs: if: >- ${{ github.actor != 'github-actions[bot]' && - github.event.repository.fork == false && ( - github.event_name == 'push' || ( + github.event_name == 'push' && + github.event.repository.fork == false + ) || + ( + github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.head_ref, 'release/') && contains(fromJSON('["MEMBER"]'), github.event.pull_request.author_association) ) From 41e87acdde265f63f829bf685518648ac129fa49 Mon Sep 17 00:00:00 2001 From: Brad White Date: Thu, 26 Mar 2026 23:47:21 -0600 Subject: [PATCH 7/9] Adjust exclude label --- .github/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/release.yml b/.github/release.yml index b8e5218..e332cdc 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -2,7 +2,7 @@ changelog: exclude: labels: - - ignore-for-release + - skip-for-release-notes categories: - title: Breaking Changes labels: From 284e3079328110699f965b5c56643201beaaa646 Mon Sep 17 00:00:00 2001 From: Brad White Date: Thu, 2 Apr 2026 09:30:40 -0600 Subject: [PATCH 8/9] fix version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e9f12af..b260203 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "elastic-github-actions", - "version": "2.1.1", + "version": "2.1.2", "description": "Elastic Organization GitHub Actions", "repository": { "type": "git", From 868dc33c934b4b60c3059b38d612a1646b6c9944 Mon Sep 17 00:00:00 2001 From: Brad White Date: Thu, 2 Apr 2026 09:39:50 -0600 Subject: [PATCH 9/9] claude review changes --- .github/workflows/build.yml | 10 +++++++++- .github/workflows/publish-release.yml | 2 +- .github/workflows/update-dist.yml | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4394a53..1a9e0fb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,5 +54,13 @@ jobs: run: pnpm build - name: Verify committed build output - if: ${{ inputs.verify_dist || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.head_ref, 'release/')) }} + if: >- + ${{ + inputs.verify_dist || + ( + github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository && + startsWith(github.head_ref, 'release/') + ) + }} run: git diff --exit-code diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index fb7d016..e707eef 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -49,7 +49,7 @@ jobs: TAG="v${VERSION}" MAJOR_TAG="${TAG%%.*}" - PREVIOUS_TAG="$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | sed -n '1p')" + PREVIOUS_TAG="$(git describe --tags --abbrev=0 --match 'v[0-9]*.[0-9]*.[0-9]*')" echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" echo "tag=${TAG}" >> "${GITHUB_OUTPUT}" diff --git a/.github/workflows/update-dist.yml b/.github/workflows/update-dist.yml index ae22b63..9d3462b 100644 --- a/.github/workflows/update-dist.yml +++ b/.github/workflows/update-dist.yml @@ -36,7 +36,7 @@ jobs: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.head_ref, 'release/') && - contains(fromJSON('["MEMBER"]'), github.event.pull_request.author_association) + contains(fromJSON('["MEMBER", "OWNER"]'), github.event.pull_request.author_association) ) ) }} @@ -74,7 +74,7 @@ jobs: GIT_COMMITTER_NAME: github-actions[bot] run: | read_package_version_from_ref() { - git show "$1:package.json" | node --print "JSON.parse(require('node:fs').readFileSync(0, 'utf8')).version" + git show "$1:package.json" | jq -r '.version' } if [ "${EVENT_NAME}" = 'pull_request' ]; then