Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ permissions:
id-token: write

jobs:
publish:
name: Publish npm package and GitHub Release
release:
name: Verify npm package and publish GitHub Release
runs-on: ubuntu-latest
environment: npm-publish
steps:
Expand Down Expand Up @@ -42,16 +42,19 @@ jobs:
- name: Run publish checks
run: npm run publish:check

- name: Publish to npm
- name: Verify npm package is published
shell: bash
run: |
if NPM_CONFIG_USERCONFIG=/dev/null npm view "devflow-native@${PACKAGE_VERSION}" version --registry https://registry.npmjs.org >/dev/null 2>&1; then
echo "devflow-native@${PACKAGE_VERSION} is already published; skipping npm publish."
echo "devflow-native@${PACKAGE_VERSION} is published."
echo "NPM_PACKAGE_PUBLISHED=true" >> "$GITHUB_ENV"
else
npm publish --access public
echo "::notice title=Manual npm publish required::devflow-native@${PACKAGE_VERSION} is not published yet. Run npm publish --access public from an authenticated local shell, then rerun this workflow."
echo "NPM_PACKAGE_PUBLISHED=false" >> "$GITHUB_ENV"
fi

- name: Create or update GitHub Release
if: env.NPM_PACKAGE_PUBLISHED == 'true'
env:
GH_TOKEN: ${{ github.token }}
shell: bash
Expand Down
55 changes: 40 additions & 15 deletions docs/release.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Release Checklist

Devflow Native is published to npm as `devflow-native`. Public releases should
use the tag-driven GitHub Actions workflow in `.github/workflows/release.yml`.
Devflow Native is published to npm as `devflow-native`. Public releases use a
local npm publish followed by the tag-driven GitHub Actions workflow in
`.github/workflows/release.yml`.

## Release Model

Expand All @@ -16,12 +17,34 @@ When a `v*` tag is pushed, the release workflow:
1. verifies that the tag matches `package.json`
2. installs Node dependencies
3. runs `npm run publish:check`
4. publishes the package to npm when that exact version is not already present
4. verifies that the exact npm package version is already published
5. creates or updates the matching GitHub Release

## Npm Trusted Publisher Setup
The workflow intentionally does not run `npm publish`. This avoids failed
release runs when GitHub Trusted Publishing is not configured for this package.
If the npm package is missing, the workflow emits a notice and exits green
without creating the GitHub Release; publish from an authenticated local shell
and rerun the workflow.

Use npm Trusted Publishing rather than a long-lived `NPM_TOKEN` secret.
## Npm Publishing Model

Use local npm authentication for publishing until npm Trusted Publishing is
configured and verified for this repository.

The known working path is:

```powershell
npm run publish:check
npm publish --access public
```

After npm publish succeeds, push the matching tag so GitHub Actions can verify
the package and create the GitHub Release without attempting a publish from CI.

## Future Trusted Publisher Setup

If moving back to CI publishing, use npm Trusted Publishing rather than a
long-lived `NPM_TOKEN` secret.

Configure the `devflow-native` package on npm with:

Expand All @@ -34,8 +57,8 @@ Environment name: npm-publish

In GitHub, create an environment named `npm-publish` and add required reviewers
when a human approval gate is desired. The workflow declares `id-token: write`
for OIDC publishing. If the npm Trusted Publisher is not configured yet, the
workflow will pass local checks and then fail at the real `npm publish` step.
for OIDC publishing. Do not re-enable CI `npm publish` until a test release has
proved that Trusted Publishing works without a permission or `E404` failure.

## Pre-Release Checks

Expand All @@ -61,26 +84,28 @@ This command verifies:
After the release commit is on `main`:

```powershell
git tag v0.1.4
npm run publish:check
npm publish --access public
git push origin main
git tag v0.1.4
git push origin v0.1.4
Comment on lines +87 to 91

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It is safer to push the release commit to the remote main branch before publishing the package to npm. If the push to main fails (for example, due to branch protection rules, hooks, or concurrent changes), you avoid a scenario where the package version is already live on npm but the corresponding source code is not yet pushed to the remote repository.

Suggested change
npm run publish:check
npm publish --access public
git push origin main
git tag v0.1.4
git push origin v0.1.4
git push origin main
npm run publish:check
npm publish --access public
git tag v0.1.4
git push origin v0.1.4

```

The workflow should publish to npm and create or update the GitHub Release from
`docs/releases/<tag>.md` when that notes file exists. If the notes file is
missing, it falls back to generated GitHub notes.
The workflow should verify the npm package and create or update the GitHub
Release from `docs/releases/<tag>.md` when that notes file exists. If the notes
file is missing, it falls back to generated GitHub notes.

## Manual Fallback

Only use this after the maintainer explicitly asks for a real public npm
release from a local terminal session:
## Manual Recovery

```powershell
npm run publish:check
npm publish --access public
gh release create v0.1.4 --title "Devflow Native v0.1.4" --notes-file docs/releases/v0.1.4.md
```

Use this only when the tag workflow could not create the GitHub Release or when
the maintainer explicitly asks for a local release recovery.

After publishing, verify from the registry:

```powershell
Expand Down