diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eeeff22..75321a6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,6 +2,11 @@ name: Release on: workflow_dispatch: + inputs: + release_tag: + description: 'Existing release tag to publish (leave empty for a dry run)' + required: false + type: string pull_request: branches: - main @@ -40,15 +45,18 @@ jobs: uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.0.0 with: fetch-depth: 0 + ref: ${{ inputs.release_tag || github.ref }} - name: Setup uses: ./.github/actions/setup - name: Validate release tag - if: github.event_name == 'push' + if: github.event_name == 'push' || inputs.release_tag != '' + env: + RELEASE_TAG: ${{ github.event_name == 'push' && github.ref_name || inputs.release_tag }} run: | git merge-base --is-ancestor HEAD origin/main - node scripts/check-release.mjs "$GITHUB_REF_NAME" + node scripts/check-release.mjs "$RELEASE_TAG" - name: Build package run: yarn build @@ -68,7 +76,9 @@ jobs: retention-days: 1 publish: - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + if: >- + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || + (github.event_name == 'workflow_dispatch' && inputs.release_tag != '') needs: package runs-on: ubuntu-latest environment: release @@ -91,12 +101,14 @@ jobs: - name: Publish with npm trusted publishing shell: bash + env: + RELEASE_TAG: ${{ github.event_name == 'push' && github.ref_name || inputs.release_tag }} run: | set -euo pipefail package_name=react-native-ease - version="${GITHUB_REF_NAME#v}" - tarball="artifacts/$package_name-$version.tgz" + version="${RELEASE_TAG#v}" + tarball="./artifacts/$package_name-$version.tgz" dist_tag=latest if [[ "$version" == *-* ]]; then dist_tag=next; fi diff --git a/RELEASE.md b/RELEASE.md index d200465..ef37f59 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -58,11 +58,9 @@ CI also builds the Android, iOS, and tvOS examples. Device behavior affected by the release still needs device validation. After this workflow has been merged into the default branch, use **Actions → -Release → Run workflow** for a publication-free integration test. The manual run -executes the full reusable CI workflow, builds and validates the npm tarball, -and uploads it as a one-day workflow artifact. The publish job only runs for a -matching pushed tag, so a manual run cannot enter the `release` environment or -publish to npm. +Release → Run workflow** with `release_tag` empty for a publication-free +integration test. The manual run executes the full reusable CI workflow, builds +and validates the npm tarball, and uploads it as a one-day workflow artifact. The dry run cannot test npm's OIDC trust relationship because npm authenticates the workflow only when `npm publish` runs. Use the first intentional prerelease @@ -99,9 +97,13 @@ move a newer dist-tag backward. new version. Never move a pushed release tag. - If a publish is interrupted, query the exact npm version before retrying. The workflow refuses registry errors other than a real missing-version response. + If the tagged workflow itself needs a fix, merge the fix to `main`, then run + the Release workflow manually with the existing tag in `release_tag`. It + checks out and validates that immutable tag before publishing its exact package. - npm versions cannot be overwritten. Publish a new version for any correction. - Do not rerun an old release to change `latest` or `next` after a newer release has advanced that dist-tag. Adding this workflow does not publish anything. npm publication begins only when -a matching release tag is pushed and the protected environment is approved. +a matching release tag is pushed, or supplied explicitly as `release_tag` to a +manual recovery run, and the protected environment is approved.