From a5c02e64607097a86b532fc2a25cac081e23e781 Mon Sep 17 00:00:00 2001 From: Oh Xyz Date: Mon, 29 Jun 2026 18:09:00 +1000 Subject: [PATCH] ci: add ungated manual dev-release trigger Add a dev_release checkbox input to publish.yml's workflow_dispatch that routes to a new manual-dev-publish job: publishes an ephemeral -dev- under the dev tag from the selected branch, with no PUBLISH environment gate. The existing formal publish (box unchecked) and auto dev-publish paths are unchanged. --- .github/workflows/publish.yml | 61 ++++++++++++++++++++++++++++++++--- RELEASING.md | 22 ++++++++++++- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e10f7e8..7968c4a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,12 +1,19 @@ name: Publish to npm -# Two publish paths share this one file because npm trusted publishing (OIDC) allows only one +# Three publish paths share this one file because npm trusted publishing (OIDC) allows only one # workflow filename per package: -# - publish (manual) : workflow_dispatch → stable release under `latest`, gated on PUBLISH env. -# - dev-publish (auto): merged PR to main → ephemeral -dev- under `dev`, unattended. +# - publish (manual) : workflow_dispatch → stable release under `latest`, gated on PUBLISH env. +# - manual-dev-publish (manual) : workflow_dispatch + dev_release checkbox → ephemeral +# -dev- under `dev` from the selected branch, ungated. +# - dev-publish (auto) : merged PR to main → ephemeral -dev- under `dev`, unattended. on: workflow_dispatch: + inputs: + dev_release: + description: 'Publish dev release from the selected branch' + type: boolean + default: false pull_request: types: [closed] branches: [main] @@ -20,7 +27,7 @@ on: jobs: publish: - if: github.event_name == 'workflow_dispatch' + if: github.event_name == 'workflow_dispatch' && inputs.dev_release != true runs-on: ubuntu-latest environment: PUBLISH permissions: @@ -90,6 +97,52 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Same ephemeral-version recipe as dev-publish, but fired manually from the selected branch + # and intentionally ungated (no `environment:`) — for cutting a dev build of in-progress work. + manual-dev-publish: + if: github.event_name == 'workflow_dispatch' && inputs.dev_release == true + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - name: Check out repository + # Checks out the branch chosen in the workflow_dispatch ref picker. + uses: actions/checkout@v6 + + - name: Set up pnpm + uses: pnpm/action-setup@v6 + with: + version: 11 + + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: '24' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - name: Compute ephemeral dev version + run: | + base="$(node -p "require('./package.json').version")" + # Next patch: split on '.', bump the last field. No semver dependency needed. + next="$(node -p "const [a,b,c]=require('./package.json').version.split('.'); [a,b,Number(c)+1].join('.')")" + sha="$(git rev-parse --short HEAD)" + devver="${next}-dev-${sha}" + # Edits the runner's copy only; --no-git-tag-version makes no commit and no tag. + npm version --no-git-tag-version "$devver" + echo "Publishing manual dev release \`$devver\` from \`${{ github.ref_name }}\` (base $base)" >> "$GITHUB_STEP_SUMMARY" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build package + run: pnpm build + + - name: Publish to npm + run: pnpm publish --no-git-checks --access public --tag dev + dev-publish: if: github.event_name == 'pull_request' && github.event.pull_request.merged == true runs-on: ubuntu-latest diff --git a/RELEASING.md b/RELEASING.md index ade8b17..189a6ef 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -5,6 +5,9 @@ Publishing is triggered manually via the **Publish to npm** workflow under `latest`, `X.Y.Z-dev.N` under `dev`. The workflow creates and pushes the matching `vX.Y.Z` git tag itself — don't tag by hand. +To cut a quick dev build of in-progress branch work, tick the **dev_release** checkbox +when dispatching — see [Ungated dev release](#ungated-dev-release) below. + ## Steps 1. **Bump the version** in `package.json` via a PR. Either edit it manually, or run an @@ -24,12 +27,29 @@ under `latest`, `X.Y.Z-dev.N` under `dev`. The workflow creates and pushes the m ```sh npm version prerelease --preid=dev --no-git-tag-version ``` + 2. **Merge the PR** into `main`. -3. **Run the workflow** — *Publish to npm* in the Actions tab, or +3. **Run the workflow** — _Publish to npm_ in the Actions tab, or `gh workflow run publish.yml`. It pauses on the `PUBLISH` environment for approval, then verifies the tag doesn't exist, builds, publishes, pushes the tag, and (for formal releases only) generates release notes. +## Ungated dev release + +To publish a `dev`-tagged build straight from a feature branch without the `PUBLISH` +approval gate: + +1. Actions → **Publish to npm** → **Run workflow**. +2. In the branch dropdown, pick the branch to publish from. +3. Tick **dev_release**, then run. + +This runs the `manual-dev-publish` job: it computes an ephemeral +`-dev-` version from the branch's `package.json` (no +`package.json` edit or version bump needed), builds, and publishes under the `dev` +tag. It does **not** pause on the `PUBLISH` environment, push a git tag, or create +release notes. With the box unchecked, dispatch behaves exactly as the formal release +above. + ## Reviewer's job The `PUBLISH` environment gates the run for approval. Before approving, confirm: