Manual Release & Publish #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Manual Release & Publish | |
| # This workflow serves as a manual fallback for releases. | |
| # The primary automated release process is handled by release-please.yml | |
| # Use this workflow only when you need to manually trigger a release. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version to release (e.g., 2.1.0)' | |
| required: true | |
| type: string | |
| prerelease: | |
| description: 'Is this a prerelease?' | |
| required: false | |
| default: false | |
| type: boolean | |
| permissions: | |
| contents: write | |
| id-token: write # Required for npm provenance | |
| jobs: | |
| validate: | |
| name: Validate Release | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.validate.outputs.version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Validate version format | |
| id: validate | |
| run: | | |
| VERSION="${{ github.event.inputs.version }}" | |
| if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then | |
| echo "::error::Invalid version format. Expected: X.Y.Z or X.Y.Z-prerelease" | |
| exit 1 | |
| fi | |
| # Check if tag already exists | |
| if git rev-parse "v$VERSION" >/dev/null 2>&1; then | |
| echo "::error::Tag v$VERSION already exists" | |
| exit 1 | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "::notice::Validated version: $VERSION" | |
| build-and-test: | |
| name: Build and Test | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '24' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install dependencies | |
| run: npm install --legacy-peer-deps | |
| env: | |
| PUPPETEER_SKIP_DOWNLOAD: 'true' | |
| - name: Run linter | |
| run: npm run lint | |
| continue-on-error: true | |
| - name: Run tests | |
| run: npm test | |
| env: | |
| CI: true | |
| - name: Build package | |
| run: npm run build | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-artifacts | |
| path: | | |
| *.min.js | |
| calendarSystems/ | |
| calendarUtils/ | |
| index.d.ts | |
| retention-days: 7 | |
| create-release: | |
| name: Create Release | |
| runs-on: ubuntu-latest | |
| needs: [validate, build-and-test] | |
| outputs: | |
| tag_name: ${{ steps.tag.outputs.tag_name }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '24' | |
| - name: Configure Git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Update package.json version | |
| run: | | |
| npm version ${{ needs.validate.outputs.version }} --no-git-tag-version | |
| git add package.json | |
| git commit -m "chore: release v${{ needs.validate.outputs.version }}" | |
| git push origin main | |
| - name: Create and push tag | |
| id: tag | |
| run: | | |
| TAG_NAME="v${{ needs.validate.outputs.version }}" | |
| git tag -a "$TAG_NAME" -m "Release $TAG_NAME" | |
| git push origin "$TAG_NAME" | |
| echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT | |
| - name: Get previous tag | |
| id: previous_tag | |
| run: | | |
| PREVIOUS_TAG=$(git tag --sort=-v:refname | grep -v "${{ steps.tag.outputs.tag_name }}" | head -n1) | |
| echo "previous_tag=$PREVIOUS_TAG" >> $GITHUB_OUTPUT | |
| echo "Previous tag: $PREVIOUS_TAG" | |
| - name: Generate release notes | |
| id: release_notes | |
| run: | | |
| VERSION="${{ needs.validate.outputs.version }}" | |
| PREVIOUS_TAG="${{ steps.previous_tag.outputs.previous_tag }}" | |
| TAG_NAME="${{ steps.tag.outputs.tag_name }}" | |
| cat > RELEASE_NOTES.md << EOF | |
| ## What's Changed | |
| EOF | |
| if [ -n "$PREVIOUS_TAG" ]; then | |
| git log ${PREVIOUS_TAG}..${TAG_NAME} --pretty=format:"* %s (%h)" >> RELEASE_NOTES.md | |
| echo "" >> RELEASE_NOTES.md | |
| echo "" >> RELEASE_NOTES.md | |
| echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREVIOUS_TAG}...${TAG_NAME}" >> RELEASE_NOTES.md | |
| else | |
| echo "Initial release" >> RELEASE_NOTES.md | |
| fi | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.tag.outputs.tag_name }} | |
| name: Release ${{ steps.tag.outputs.tag_name }} | |
| body_path: RELEASE_NOTES.md | |
| draft: false | |
| prerelease: ${{ github.event.inputs.prerelease }} | |
| generate_release_notes: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| publish-npm: | |
| name: Publish to npm | |
| runs-on: ubuntu-latest | |
| needs: [validate, create-release] | |
| permissions: | |
| contents: read | |
| id-token: write # Required for npm provenance | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: v${{ needs.validate.outputs.version }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '24' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install dependencies | |
| run: npm install --legacy-peer-deps | |
| env: | |
| PUPPETEER_SKIP_DOWNLOAD: 'true' | |
| - name: Build package | |
| run: npm run build | |
| - name: Publish to npm with provenance | |
| run: npm publish --access public --provenance | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Notify success | |
| run: | | |
| echo "::notice::Successfully published @calidy/dayjs-calendarsystems@${{ needs.validate.outputs.version }} to npm" | |
| echo "Package URL: https://www.npmjs.com/package/@calidy/dayjs-calendarsystems/v/${{ needs.validate.outputs.version }}" | |
| upload-release-assets: | |
| name: Upload Release Assets | |
| runs-on: ubuntu-latest | |
| needs: [validate, create-release, publish-npm] | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: v${{ needs.validate.outputs.version }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '24' | |
| - name: Install dependencies | |
| run: npm install --legacy-peer-deps | |
| env: | |
| PUPPETEER_SKIP_DOWNLOAD: 'true' | |
| - name: Build package | |
| run: npm run build | |
| - name: Upload release assets | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.create-release.outputs.tag_name }} | |
| files: | | |
| *.min.js | |
| LICENSE.md | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| notify-completion: | |
| name: Release Notification | |
| runs-on: ubuntu-latest | |
| needs: [validate, publish-npm, upload-release-assets] | |
| if: always() | |
| steps: | |
| - name: Check release status | |
| run: | | |
| if [ "${{ needs.publish-npm.result }}" == "success" ]; then | |
| echo "::notice::Release v${{ needs.validate.outputs.version }} completed successfully!" | |
| echo "" | |
| echo "Summary:" | |
| echo " - Version: ${{ needs.validate.outputs.version }}" | |
| echo " - npm: https://www.npmjs.com/package/@calidy/dayjs-calendarsystems" | |
| echo " - GitHub: https://github.com/${{ github.repository }}/releases/tag/v${{ needs.validate.outputs.version }}" | |
| else | |
| echo "::error::Release failed!" | |
| echo "npm publish: ${{ needs.publish-npm.result }}" | |
| exit 1 | |
| fi |