diff --git a/README.md b/README.md index ec6d602..86def65 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,9 @@ When a PR is merged (and the release label requirement is met, if enabled): 2. Analyzes all commits since that tag using conventional commit prefixes 3. Determines the appropriate semver bump (major, minor, or patch) 4. Creates a `release/` branch -5. Optionally generates/updates `CHANGELOG.md` -6. Opens a release PR with a summary of what's included +5. Bumps `package.json` version if npm publishing is enabled +6. Optionally generates/updates `CHANGELOG.md` +7. Opens a release PR with a summary of what's included ### Phase 2: Finalize the release @@ -33,6 +34,7 @@ When the release PR (detected by the `release/` branch prefix) is merged: 1. Creates an annotated git tag 2. Optionally creates a GitHub release with auto-generated release notes +3. Optionally publishes to an npm registry ## Usage @@ -76,6 +78,9 @@ jobs: | `create-release` | Create a GitHub release when the release PR is merged | No | `true` | | `draft-release` | Create the GitHub release as a draft (unpublished) | No | `true` | | `changelog` | Generate or update `CHANGELOG.md` in the release PR | No | `true` | +| `publish-npm` | Publish the package to an npm registry when the release PR is merged | No | `false` | +| `npm-token` | Auth token for the npm registry (required when `publish-npm` is `true`) | No | — | +| `npm-registry` | npm registry URL (set to `https://npm.pkg.github.com` for GitHub Packages) | No | `https://registry.npmjs.org` | ## Outputs @@ -163,6 +168,27 @@ Commits that can't be linked to a PR will reference the commit SHA instead. version-prefix: '' ``` +### Publish to npm + +```yaml +- uses: offload-project/release-champion@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + publish-npm: true + npm-token: ${{ secrets.NPM_TOKEN }} +``` + +### Publish to GitHub Packages + +```yaml +- uses: offload-project/release-champion@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + publish-npm: true + npm-token: ${{ secrets.GITHUB_TOKEN }} + npm-registry: 'https://npm.pkg.github.com' +``` + ### Tag only, no GitHub release ```yaml @@ -190,8 +216,7 @@ steps: ## Permissions -The workflow needs `contents: write` (for tags and releases) and `pull-requests: write` (for creating PRs). If using the -default `GITHUB_TOKEN`, set these under the job's `permissions` key. +The workflow needs `contents: write` (for tags and releases) and `pull-requests: write` (for creating PRs). If publishing to GitHub Packages, also add `packages: write`. If using the default `GITHUB_TOKEN`, set these under the job's `permissions` key. ## Tests diff --git a/action.yml b/action.yml index cd2e421..f6638ec 100644 --- a/action.yml +++ b/action.yml @@ -36,6 +36,17 @@ inputs: description: 'Generate or update CHANGELOG.md in the release PR' required: false default: 'true' + publish-npm: + description: 'Publish the package to an npm registry when the release PR is merged' + required: false + default: 'false' + npm-token: + description: 'Auth token for the npm registry (required when publish-npm is true)' + required: false + npm-registry: + description: 'npm registry URL (e.g., https://npm.pkg.github.com for GitHub Packages)' + required: false + default: 'https://registry.npmjs.org' outputs: version: @@ -66,6 +77,9 @@ runs: INPUT_CREATE_RELEASE: ${{ inputs.create-release }} INPUT_DRAFT_RELEASE: ${{ inputs.draft-release }} INPUT_CHANGELOG: ${{ inputs.changelog }} + INPUT_PUBLISH_NPM: ${{ inputs.publish-npm }} + INPUT_NPM_TOKEN: ${{ inputs.npm-token }} + INPUT_NPM_REGISTRY: ${{ inputs.npm-registry }} PR_NUMBER: ${{ github.event.pull_request.number }} PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} PR_MERGED: ${{ github.event.pull_request.merged }} diff --git a/scripts/create-release-pr.sh b/scripts/create-release-pr.sh index 7ddf049..ab967c4 100755 --- a/scripts/create-release-pr.sh +++ b/scripts/create-release-pr.sh @@ -54,6 +54,21 @@ main() { git checkout -b "$branch_name" + # Bump package.json version if npm publishing is enabled + if [[ "${INPUT_PUBLISH_NPM:-false}" == "true" ]]; then + if [[ ! -f package.json ]]; then + echo "::error::publish-npm is enabled but no package.json found" + exit 1 + fi + echo "Bumping package.json to ${new_version}" + npm version "$new_version" --no-git-tag-version + git add package.json + if [[ -f package-lock.json ]] && ! git diff --staged --quiet package-lock.json 2>/dev/null; then + git add package-lock.json + fi + git commit -m "chore: bump package version to ${new_version}" + fi + # Generate changelog if enabled if [[ "$INPUT_CHANGELOG" == "true" ]]; then echo "Generating changelog..." @@ -124,6 +139,14 @@ generate_pr_body() { fi fi + if [[ "${INPUT_PUBLISH_NPM:-false}" == "true" ]]; then + if [[ "$INPUT_NPM_REGISTRY" == *"npm.pkg.github.com"* ]]; then + body+="*This release will be published to GitHub Packages.*"$'\n' + else + body+="*This release will be published to npm.*"$'\n' + fi + fi + echo "$body" } diff --git a/scripts/finalize-release.sh b/scripts/finalize-release.sh index 40e534e..2d8f6bf 100755 --- a/scripts/finalize-release.sh +++ b/scripts/finalize-release.sh @@ -58,6 +58,37 @@ main() { echo "release_url=${release_url}" >> "$GITHUB_OUTPUT" fi + # Publish to npm + if [[ "${INPUT_PUBLISH_NPM:-false}" == "true" ]]; then + echo "::group::Publishing to npm" + + if ! command -v npm &>/dev/null; then + echo "::error::npm is not installed. Add a setup-node step before release-champion." + exit 1 + fi + + if [[ -z "${INPUT_NPM_TOKEN:-}" ]]; then + echo "::error::npm-token is required when publish-npm is true" + exit 1 + fi + + local registry="${INPUT_NPM_REGISTRY:-https://registry.npmjs.org}" + local registry_host + registry_host=$(echo "$registry" | sed 's|https:||') + + echo "${registry_host}:_authToken=${INPUT_NPM_TOKEN}" > .npmrc + echo "registry=${registry}" >> .npmrc + + npm publish + + rm -f .npmrc + + local pkg_name + pkg_name=$(node -p "require('./package.json').name") + echo "Published ${pkg_name}@${version}" + echo "::endgroup::" + fi + echo "version=${version}" >> "$GITHUB_OUTPUT" }