Skip to content

Release Packages

Release Packages #40

name: Release Packages
on:
workflow_dispatch:
inputs:
packages:
description: 'Packages to release (comma-separated)'
required: true
type: string
default: '@novu/js,@novu/react,@novu/nextjs,@novu/react-native'
version:
description: 'Version to release (e.g., v3.0.0)'
required: true
type: string
default: 'v3.0.0'
previous_tag:
description: 'Previous tag to generate changelog from (e.g., @novu/[email protected])'
required: true
type: string
default: '@novu/[email protected]'
nightly:
description: 'Publish as nightly release'
required: true
type: boolean
default: false
create_github_release:
description: 'Create GitHub releases for the packages'
required: true
type: boolean
default: false
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
outputs:
pr_number: ${{ !github.event.inputs.nightly && steps.create-pr.outputs.pull-request-number || '' }}
pr_url: ${{ !github.event.inputs.nightly && steps.create-pr.outputs.pull-request-url || '' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10.11.0
run_install: false
- name: Setup Node Version
uses: actions/setup-node@v4
with:
node-version: '20.19.0'
cache: 'pnpm'
registry-url: 'https://registry.npmjs.org'
- name: Install Dependencies
shell: bash
run: |
pnpm install --frozen-lockfile
pnpm nx --version
pnpm list nx
- name: Set version for nightly
if: ${{ github.event.inputs.nightly }}
run: |
DATE=$(date +'%Y%m%d')
COMMIT_SHA=$(git rev-parse --short HEAD)
echo "NIGHTLY_VERSION=${{ github.event.inputs.version }}-nightly.${DATE}.${COMMIT_SHA}" >> $GITHUB_ENV
echo "Using nightly version: $NIGHTLY_VERSION"
- name: Configure Git
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
- name: Release version (without commit)
run: |
if [ "${{ github.event.inputs.nightly }}" = "true" ]; then
echo "Running nightly release with version: ${{ env.NIGHTLY_VERSION }}"
pnpm nx release version ${{ env.NIGHTLY_VERSION }} --projects=${{ github.event.inputs.packages }} --preid nightly --git-commit=false --verbose
else
echo "Running regular release with version: ${{ github.event.inputs.version }}"
pnpm nx release version ${{ github.event.inputs.version }} --projects=${{ github.event.inputs.packages }} --git-commit=false --verbose
fi
- name: Generate changelog (without commit)
run: |
if [ "${{ github.event.inputs.nightly }}" = "true" ]; then
pnpm nx release changelog ${{ env.NIGHTLY_VERSION }} --projects=${{ github.event.inputs.packages }} --from=${{ github.event.inputs.previous_tag }} --git-commit=false
else
pnpm nx release changelog ${{ github.event.inputs.version }} --projects=${{ github.event.inputs.packages }} --from=${{ github.event.inputs.previous_tag }} --git-commit=false
fi
- name: Build packages
run: pnpm run build:packages
- name: Publish packages (nightly only)
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ "${{ github.event.inputs.nightly }}" = "true" ]; then
export NX_RELEASE_TAG=nightly
pnpm nx run-many -t nx-release-publish --projects=${{ github.event.inputs.packages }}
else
echo "Skipping publish for non-nightly release"
fi
- name: Debug git status
run: |
echo "=== Git Status ==="
git status
echo "=== Git Log (last 3 commits) ==="
git log --oneline -3
echo "=== Changed Files ==="
git diff --name-only HEAD~1 || echo "No commits to compare against"
- name: Reset to clean state for PR creation
run: |
echo "=== Resetting any commits made by NX ==="
# If NX created commits, reset to the original commit but keep changes
if [ "$(git log --oneline HEAD~1..HEAD | wc -l)" -gt "0" ]; then
echo "Found $(git log --oneline HEAD~1..HEAD | wc -l) commits since start"
git reset --soft HEAD~$(git log --oneline HEAD~1..HEAD | wc -l)
echo "Reset commits, changes are now staged"
git status
else
echo "No commits to reset"
# Stage any unstaged changes
git add -A
fi
- name: Create Pull Request
id: create-pr
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "chore: release ${{ github.event.inputs.version }} (${{ github.event.inputs.packages }})"
title: "🚀 Release ${{ github.event.inputs.version }} - ${{ github.event.inputs.packages }}"
body: |
## 🚀 Release ${{ github.event.inputs.version }}
This PR contains the release changes for version **${{ github.event.inputs.version }}**
### 📦 Packages Released:
```
${{ github.event.inputs.packages }}
```
### 🔄 Changes:
- Updated package versions to ${{ github.event.inputs.version }}
- Generated changelogs from ${{ github.event.inputs.previous_tag }}
- Built packages for release
**Please review the changes and merge when ready for the release to be tagged and GitHub releases to be created.**
branch: release-${{ github.event.inputs.version }}
base: next
delete-branch: false
post_release:
needs: release
if: ${{ !github.event.inputs.nightly && needs.release.outputs.pr_number }}
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
actions: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
ref: next
- name: Wait for manual PR merge
id: wait_merge
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "📋 Waiting for manual merge of PR #${{ needs.release.outputs.pr_number }}"
echo "🔗 PR URL: ${{ needs.release.outputs.pr_url }}"
echo "Please review and merge the PR manually. This workflow will wait up to 30 minutes..."
# Wait up to 30 minutes for manual merge
for i in {1..180}; do
status=$(gh pr view ${{ needs.release.outputs.pr_number }} --json state --jq '.state')
if [ "$status" = "MERGED" ]; then
echo "✅ PR has been merged!"
echo "merged=true" >> $GITHUB_OUTPUT
break
fi
echo "⏳ Still waiting for manual merge... (attempt $i/180)"
sleep 10
done
# Final check
status=$(gh pr view ${{ needs.release.outputs.pr_number }} --json state --jq '.state')
if [ "$status" != "MERGED" ]; then
echo "❌ PR was not merged within the timeout period (30 minutes). Current status: $status"
echo "You can manually run the 'Manual Post-Release' workflow after merging the PR."
echo "merged=false" >> $GITHUB_OUTPUT
exit 1
fi
- name: Trigger Manual Post-Release Workflow
if: steps.wait_merge.outputs.merged == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "🚀 Triggering Manual Post-Release workflow..."
gh workflow run manual-post-release.yml \
-f packages="${{ github.event.inputs.packages }}" \
-f version="${{ github.event.inputs.version }}" \
-f create_github_release="${{ github.event.inputs.create_github_release }}"
echo "✅ Manual Post-Release workflow has been triggered!"
echo "You can monitor its progress in the Actions tab."