Publish New Package Version #71
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: Publish New Package Version | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| package: | |
| type: choice | |
| description: Package name | |
| options: | |
| - offchain-manager | |
| - addresses | |
| - indexer | |
| - mint-manager | |
| - avatar | |
| version: | |
| type: string | |
| description: "version" | |
| publish: | |
| type: boolean | |
| description: Publish to npm | |
| default: false | |
| changelog: | |
| type: string | |
| description: "Changelog (required if publishing, markdown format, do NOT include version or date header. Use sections like ### Added, ### Changed, etc. Each section should be on a new line, and bullet points should start with -)" | |
| default: "" | |
| discord_notify: | |
| type: boolean | |
| description: "If checked, the release will notify on discord" | |
| default: false | |
| jobs: | |
| build-and-publish: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| id-token: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Use Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24 | |
| registry-url: "https://registry.npmjs.org/" | |
| - name: Read previous version from package.json | |
| id: previous-version | |
| working-directory: packages/${{ inputs.package }} | |
| run: | | |
| version=$(jq -r '.version' package.json) | |
| echo "Previous version: $version" | |
| echo "version=$version" >> $GITHUB_OUTPUT | |
| - name: Extract new version from input | |
| id: current-version | |
| env: | |
| INPUT_VERSION: ${{ inputs.version }} | |
| run: | | |
| # Ensure semver format | |
| if [[ ! "$INPUT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then | |
| echo "❌ Invalid version format. Must follow semantic versioning (e.g., 1.2.3 or 1.2.3-suffix)" | |
| exit 1 | |
| fi | |
| version="${{ inputs.version }}" | |
| echo "Current version: $version" | |
| echo "version=$version" >> $GITHUB_OUTPUT | |
| - name: Check valid version increase | |
| uses: aleoyakas/check-semver-increased-action@v1 | |
| id: check-version | |
| with: | |
| current-version: ${{ steps.current-version.outputs.version }} | |
| previous-version: ${{ steps.previous-version.outputs.version }} | |
| - name: Fail if version not increased | |
| if: steps.check-version.outputs.is-version-increased != 'true' | |
| run: | | |
| echo "❌ Version has not increased. Please bump the version above ${{ steps.previous-version.outputs.version }}" | |
| exit 1 | |
| - name: Install dependencies | |
| run: npm ci | |
| # Build workspace dependencies first (in dependency order) | |
| - name: Build workspace dependencies | |
| run: | | |
| # Build addresses package first since mint-manager depends on it | |
| if [ "${{ inputs.package }}" = "mint-manager" ]; then | |
| echo "Building @thenamespace/addresses dependency..." | |
| npm run -w @thenamespace/addresses build | |
| fi | |
| # Add other workspace dependencies here as needed | |
| # Example: if a package depends on indexer, add: | |
| # if [ "${{ inputs.package }}" = "some-package" ]; then | |
| # echo "Building @thenamespace/indexer dependency..." | |
| # npm run -w @thenamespace/indexer build | |
| # fi | |
| # Future-proof: Check for any @thenamespace/* dependencies in package.json | |
| # and build them if they exist as workspace packages | |
| echo "Checking for other workspace dependencies..." | |
| WORKSPACE_DEPS=$(jq -r '.dependencies | keys[] | select(startswith("@thenamespace/"))' packages/${{ inputs.package }}/package.json 2>/dev/null || echo "") | |
| for dep in $WORKSPACE_DEPS; do | |
| if [ "$dep" != "@thenamespace/${{ inputs.package }}" ] && [ -d "packages/${dep#@thenamespace/}" ]; then | |
| echo "Building workspace dependency: $dep" | |
| npm run -w "$dep" build | |
| fi | |
| done | |
| - name: Build selected package | |
| working-directory: packages/${{ inputs.package }} | |
| run: npm run build | |
| - name: Update package version in package.json | |
| working-directory: packages/${{ inputs.package }} | |
| run: | | |
| npm version ${{ inputs.version }} --no-git-tag-version | |
| - name: Validate changelog if publishing | |
| if: ${{ inputs.publish == true }} | |
| run: | | |
| if [ -z "${{ inputs.changelog }}" ]; then | |
| echo "❌ Changelog is required when publishing." | |
| exit 1 | |
| fi | |
| - name: Publish package to npm registry | |
| if: ${{ inputs.publish == true }} | |
| working-directory: packages/${{ inputs.package }} | |
| run: npm publish --provenance --access public | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Commit and push version bump and tag | |
| if: ${{ inputs.publish == true }} | |
| env: | |
| VERSION: ${{ inputs.version }} | |
| CHANGELOG: ${{ inputs.changelog }} | |
| PACKAGE: ${{ inputs.package }} | |
| GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| echo "📝 Inserting changelog for $VERSION" | |
| FILE="changelog/${PACKAGE}-changelog.md" | |
| TEMP_FILE="${FILE}.tmp" | |
| DATE=$(date +'%Y-%m-%d') | |
| HEADER="## [${VERSION}] - ${DATE}" | |
| if [ ! -f "$FILE" ]; then | |
| echo -e "# Changelog\n" > "$FILE" | |
| fi | |
| # Find the insertion point - look for the first version entry (## [version]) | |
| # This ensures we insert after the intro section but before any existing versions | |
| FIRST_VERSION_LINE=$(grep -n "^## \[" "$FILE" | head -1 | cut -d: -f1) | |
| if [ -z "$FIRST_VERSION_LINE" ]; then | |
| # No existing versions found, append to end of file | |
| INSERTION_LINE=$(wc -l < "$FILE") | |
| else | |
| # Insert before the first version entry | |
| INSERTION_LINE=$((FIRST_VERSION_LINE - 1)) | |
| fi | |
| # Process the changelog input to ensure proper formatting | |
| # Python3 is pre-installed on ubuntu-latest runners (free, no extra cost) | |
| PRETTY_CHANGELOG=$(python3 scripts/format-changelog.py "$CHANGELOG") | |
| # Write the file up to insertion point | |
| if [ "$INSERTION_LINE" -gt 0 ]; then | |
| head -n "$INSERTION_LINE" "$FILE" > "$TEMP_FILE" | |
| else | |
| # If no insertion point found, start with the header | |
| echo -e "# Changelog\n" > "$TEMP_FILE" | |
| fi | |
| # Add the new entry with proper formatting | |
| echo -e "\n${HEADER}\n\n${PRETTY_CHANGELOG}\n" >> "$TEMP_FILE" | |
| # Add the rest of the file (existing versions) | |
| if [ "$INSERTION_LINE" -gt 0 ] && [ "$INSERTION_LINE" -lt $(wc -l < "$FILE") ]; then | |
| tail -n "+$((INSERTION_LINE + 1))" "$FILE" >> "$TEMP_FILE" | |
| fi | |
| mv "$TEMP_FILE" "$FILE" | |
| # Commit the updated package.json with new version | |
| git add packages/$PACKAGE/package.json | |
| git add changelog/* | |
| git commit -m "chore($PACKAGE): bump version to $VERSION" | |
| # Create a tag with the version | |
| TAG="${PACKAGE}-${VERSION}" | |
| git tag -a "$TAG" -m "Release $TAG" | |
| # Push commit and tag | |
| git push origin HEAD | |
| git push origin "$TAG" | |
| - name: Post update to Discord | |
| if: ${{ inputs.discord_notify == true }} | |
| env: | |
| DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK }} | |
| VERSION: ${{ inputs.version }} | |
| CHANGELOG: ${{ inputs.changelog }} | |
| PACKAGE: ${{ inputs.package }} | |
| run: | | |
| MESSAGE="Published a new version of *@thenamespace/${PACKAGE}*, version: \`${VERSION}\`!\n\n📝 ${CHANGELOG}" | |
| curl -X POST -H "Content-Type: application/json" \ | |
| -d "{\"content\": \"$MESSAGE\"}" \ | |
| "$DISCORD_WEBHOOK_URL" |