chore: weekly release 2026-03-27 #8
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: Release npm (JS & CLI) | |
| on: | |
| issue_comment: | |
| types: [created] | |
| workflow_dispatch: | |
| inputs: | |
| package: | |
| description: 'Package to release (cli or js)' | |
| required: true | |
| type: choice | |
| options: | |
| - cli | |
| - js | |
| release_type: | |
| description: 'Release type' | |
| required: true | |
| type: choice | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| prerelease: | |
| description: 'Prerelease tag (leave empty for stable release)' | |
| required: false | |
| type: choice | |
| options: | |
| - '' | |
| - beta | |
| - alpha | |
| - rc | |
| ref: | |
| description: 'Branch/ref to release from (default: main)' | |
| required: false | |
| type: string | |
| default: 'main' | |
| permissions: | |
| contents: write | |
| issues: write | |
| pull-requests: write | |
| id-token: write # Required for npm Trusted Publishers (OIDC) | |
| env: | |
| NODE_VERSION: '20' | |
| jobs: | |
| parse: | |
| if: > | |
| github.event_name == 'issue_comment' && | |
| (contains(github.event.comment.body, '!release') || | |
| contains(github.event.comment.body, '!Release') || | |
| contains(github.event.comment.body, '!RELEASE')) && | |
| github.event.comment.user.type != 'Bot' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_release: ${{ steps.parse.outputs.should_release }} | |
| package: ${{ steps.parse.outputs.package }} | |
| release_type: ${{ steps.parse.outputs.release_type }} | |
| prerelease: ${{ steps.parse.outputs.prerelease }} | |
| npm_tag: ${{ steps.parse.outputs.npm_tag }} | |
| ref: ${{ steps.parse.outputs.ref }} | |
| pr_branch: ${{ steps.parse.outputs.pr_branch }} | |
| pr_title: ${{ steps.parse.outputs.pr_title }} | |
| pr_url: ${{ steps.parse.outputs.pr_url }} | |
| issue_number: ${{ steps.parse.outputs.issue_number }} | |
| requested_by: ${{ steps.parse.outputs.requested_by }} | |
| request_url: ${{ steps.parse.outputs.request_url }} | |
| steps: | |
| - name: Parse release command | |
| id: parse | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const allowedPackages = ['cli', 'js']; | |
| const allowedBumps = ['patch', 'minor', 'major']; | |
| const allowedPrereleaseTags = ['beta', 'alpha', 'rc']; | |
| const body = context.payload.comment.body.trim(); | |
| const match = body.match(/!release\s+(\S+)\s+(\S+)(?:\s+(\S+))?/i); | |
| if (!match) { | |
| return; | |
| } | |
| const packageName = match[1].toLowerCase(); | |
| const releaseType = match[2].toLowerCase(); | |
| const prereleaseTag = match[3] ? match[3].toLowerCase() : ''; | |
| const allowedAssociation = ['OWNER', 'MEMBER', 'COLLABORATOR']; | |
| const association = context.payload.comment.author_association; | |
| const actor = context.payload.comment.user.login; | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const issueNumber = context.payload.issue.number; | |
| // python/py packages are handled by release-python.yml β skip silently | |
| const pythonPackages = ['python', 'py']; | |
| if (pythonPackages.includes(packageName)) { | |
| return; | |
| } | |
| // go/golang packages are handled by release-go.yml β skip silently | |
| const goPackages = ['go', 'golang']; | |
| if (goPackages.includes(packageName)) { | |
| return; | |
| } | |
| const invalidPackage = !allowedPackages.includes(packageName); | |
| const invalidBump = !allowedBumps.includes(releaseType); | |
| const invalidPrerelease = prereleaseTag && !allowedPrereleaseTags.includes(prereleaseTag); | |
| if (invalidPackage || invalidBump || invalidPrerelease) { | |
| const message = [ | |
| `β οΈ @${actor} I couldn't parse the release command.`, | |
| '', | |
| 'Expected format: `!release <cli|js|python|go> <patch|minor|major> [beta|alpha|rc]`', | |
| '', | |
| 'Examples:', | |
| '- `!release cli patch` - stable release', | |
| '- `!release js minor beta` - beta release', | |
| '- `!release python minor` - Python SDK release', | |
| '- `!release go minor` - Go SDK release' | |
| ]; | |
| await github.rest.issues.createComment({ | |
| owner, | |
| repo, | |
| issue_number: issueNumber, | |
| body: message.join('\n') | |
| }); | |
| return; | |
| } | |
| if (!allowedAssociation.includes(association)) { | |
| const message = [ | |
| `β @${actor} you do not have permission to trigger releases.`, | |
| '', | |
| 'Please contact the repository maintainers if this is unexpected.' | |
| ]; | |
| await github.rest.issues.createComment({ | |
| owner, | |
| repo, | |
| issue_number: issueNumber, | |
| body: message.join('\n') | |
| }); | |
| return; | |
| } | |
| let ref = 'main'; | |
| let prBranch = ''; | |
| let prTitle = ''; | |
| let prUrl = ''; | |
| if (context.payload.issue.pull_request) { | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner, | |
| repo, | |
| pull_number: issueNumber | |
| }); | |
| if (!pr.head.repo || pr.head.repo.full_name !== `${owner}/${repo}`) { | |
| const message = [ | |
| `β @${actor} releases from forked branches are not supported.`, | |
| '', | |
| 'Please push the branch to this repository or run the release manually in Actions.' | |
| ]; | |
| await github.rest.issues.createComment({ | |
| owner, | |
| repo, | |
| issue_number: issueNumber, | |
| body: message.join('\n') | |
| }); | |
| return; | |
| } | |
| ref = pr.head.ref; | |
| prBranch = pr.head.ref; | |
| prTitle = pr.title; | |
| prUrl = pr.html_url; | |
| } | |
| const npmTag = prereleaseTag || 'latest'; | |
| const releaseTypeLabel = prereleaseTag ? `${releaseType} (${prereleaseTag})` : releaseType; | |
| const lines = [ | |
| `π @${actor} release command accepted: \`${packageName}\` \`${releaseTypeLabel}\`.`, | |
| '', | |
| 'The release workflow is queued; results will be posted here.' | |
| ]; | |
| if (prBranch) { | |
| lines.splice(2, 0, `Target branch: \`${prBranch}\` (open PR). Version commits will be pushed to this branch.`); | |
| } | |
| if (prereleaseTag) { | |
| lines.splice(2, 0, `π¦ Prerelease tag: \`${prereleaseTag}\` (will publish to npm with tag \`${npmTag}\`)`); | |
| } | |
| const message = lines.join('\n'); | |
| await github.rest.issues.createComment({ | |
| owner, | |
| repo, | |
| issue_number: issueNumber, | |
| body: message | |
| }); | |
| core.setOutput('should_release', 'true'); | |
| core.setOutput('package', packageName); | |
| core.setOutput('release_type', releaseType); | |
| core.setOutput('prerelease', prereleaseTag); | |
| core.setOutput('npm_tag', npmTag); | |
| core.setOutput('ref', ref); | |
| core.setOutput('pr_branch', prBranch); | |
| core.setOutput('pr_title', prTitle); | |
| core.setOutput('pr_url', prUrl); | |
| core.setOutput('issue_number', issueNumber); | |
| core.setOutput('requested_by', actor); | |
| core.setOutput('request_url', context.payload.comment.html_url); | |
| release: | |
| needs: [parse] | |
| if: | | |
| always() && | |
| ( | |
| (needs.parse.result == 'success' && needs.parse.outputs.should_release == 'true') || | |
| (github.event_name == 'workflow_dispatch') | |
| ) | |
| concurrency: | |
| group: release-${{ github.event_name == 'workflow_dispatch' && inputs.package || needs.parse.outputs.package }}-${{ github.event_name == 'workflow_dispatch' && inputs.ref || needs.parse.outputs.ref }} | |
| cancel-in-progress: false | |
| runs-on: ubuntu-latest | |
| env: | |
| PACKAGE: ${{ github.event_name == 'workflow_dispatch' && inputs.package || needs.parse.outputs.package }} | |
| RELEASE_TYPE: ${{ github.event_name == 'workflow_dispatch' && inputs.release_type || needs.parse.outputs.release_type }} | |
| PRERELEASE: ${{ github.event_name == 'workflow_dispatch' && inputs.prerelease || needs.parse.outputs.prerelease }} | |
| NPM_TAG: ${{ github.event_name == 'workflow_dispatch' && (inputs.prerelease || 'latest') || needs.parse.outputs.npm_tag }} | |
| SOURCE_REF: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || needs.parse.outputs.ref }} | |
| ISSUE_NUMBER: ${{ needs.parse.outputs.issue_number }} | |
| REQUESTED_BY: ${{ github.event_name == 'workflow_dispatch' && github.actor || needs.parse.outputs.requested_by }} | |
| REQUEST_URL: ${{ needs.parse.outputs.request_url }} | |
| PR_TITLE: ${{ needs.parse.outputs.pr_title }} | |
| PR_URL: ${{ needs.parse.outputs.pr_url }} | |
| PR_BRANCH: ${{ needs.parse.outputs.pr_branch }} | |
| steps: | |
| - name: Validate context | |
| run: | | |
| set -e | |
| if [ -z "${PACKAGE:-}" ]; then | |
| echo "PACKAGE is not set" | |
| exit 1 | |
| fi | |
| case "$PACKAGE" in | |
| cli|js) ;; | |
| *) | |
| echo "Unsupported package: $PACKAGE" | |
| exit 1 | |
| ;; | |
| esac | |
| if [ -z "${RELEASE_TYPE:-}" ]; then | |
| echo "RELEASE_TYPE is not set" | |
| exit 1 | |
| fi | |
| case "$RELEASE_TYPE" in | |
| patch|minor|major) ;; | |
| *) | |
| echo "Unsupported release type: $RELEASE_TYPE" | |
| exit 1 | |
| ;; | |
| esac | |
| if [ -z "${SOURCE_REF:-}" ]; then | |
| echo "SOURCE_REF is not set" | |
| exit 1 | |
| fi | |
| - name: Checkout source | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ env.SOURCE_REF }} | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| - name: Install workspace dependencies | |
| run: bun install | |
| - name: Build js SDK (dependency for cli) | |
| if: env.PACKAGE == 'cli' | |
| working-directory: js | |
| run: bun run build | |
| - name: Bump package version | |
| id: bump | |
| run: node scripts/bump-version.js "$PACKAGE" "$RELEASE_TYPE" "$PRERELEASE" | |
| - name: Format package.json | |
| working-directory: ${{ env.PACKAGE }} | |
| run: bun run fmt | |
| - name: Export version metadata | |
| run: | | |
| echo "NEW_VERSION=${{ steps.bump.outputs.version }}" >> "$GITHUB_ENV" | |
| echo "TAG_NAME=${PACKAGE}-v${{ steps.bump.outputs.version }}" >> "$GITHUB_ENV" | |
| - name: Capture package metadata | |
| id: pkgmeta | |
| run: | | |
| npm_name=$(node -e "console.log(require('./${PACKAGE}/package.json').name)") | |
| npm_url=$(node -e "const name = require('./${PACKAGE}/package.json').name; console.log('https://www.npmjs.com/package/' + encodeURIComponent(name));") | |
| echo "npm_name=$npm_name" >> "$GITHUB_OUTPUT" | |
| echo "npm_url=$npm_url" >> "$GITHUB_OUTPUT" | |
| - name: Run lint | |
| working-directory: ${{ env.PACKAGE }} | |
| run: bun run lint | |
| - name: Run type check | |
| working-directory: ${{ env.PACKAGE }} | |
| run: bun run type-check | |
| - name: Build package | |
| working-directory: ${{ env.PACKAGE }} | |
| run: bun run build | |
| - name: Run tests | |
| working-directory: ${{ env.PACKAGE }} | |
| run: bun run test | |
| - name: Analyze package contents | |
| id: pack_info | |
| working-directory: ${{ env.PACKAGE }} | |
| run: | | |
| npm pack --dry-run > pack_output.txt 2>&1 | |
| # Extract package size info | |
| package_size=$(grep "package size:" pack_output.txt | awk '{print $4, $5}') | |
| unpacked_size=$(grep "unpacked size:" pack_output.txt | awk '{print $4, $5}') | |
| total_files=$(grep "total files:" pack_output.txt | awk '{print $4}') | |
| # Get file list (skip the first few lines and last few lines of npm notice) | |
| file_list=$(sed -n '/Tarball Contents/,/Tarball Details/p' pack_output.txt | \ | |
| grep "npm notice" | \ | |
| grep -v "Tarball Contents" | \ | |
| grep -v "Tarball Details" | \ | |
| sed 's/npm notice //g' | \ | |
| head -20) | |
| # Save to GitHub output (escape newlines for multiline output) | |
| echo "package_size=${package_size}" >> "$GITHUB_OUTPUT" | |
| echo "unpacked_size=${unpacked_size}" >> "$GITHUB_OUTPUT" | |
| echo "total_files=${total_files}" >> "$GITHUB_OUTPUT" | |
| # Save file list with proper multiline format | |
| echo "file_list<<EOF" >> "$GITHUB_OUTPUT" | |
| echo "$file_list" >> "$GITHUB_OUTPUT" | |
| echo "EOF" >> "$GITHUB_OUTPUT" | |
| # Clean up | |
| rm pack_output.txt | |
| - name: Generate changelog | |
| working-directory: ${{ env.PACKAGE }} | |
| run: | | |
| npm install -g conventional-changelog-cli conventional-changelog-conventionalcommits | |
| # Update CHANGELOG.md (prepends latest release) | |
| conventional-changelog -p conventionalcommits \ | |
| --commit-path . \ | |
| -i CHANGELOG.md \ | |
| -s \ | |
| --pkg-path ./package.json \ | |
| -n ../changelog.config.js \ | |
| --tag-prefix "${PACKAGE}-v" | |
| # Generate release notes for GitHub Release body | |
| conventional-changelog -p conventionalcommits \ | |
| --commit-path . \ | |
| -o RELEASE_NOTES.md \ | |
| --pkg-path ./package.json \ | |
| -n ../changelog.config.js \ | |
| --tag-prefix "${PACKAGE}-v" | |
| - name: Commit version change | |
| run: | | |
| git add "${PACKAGE}/package.json" | |
| git add "${PACKAGE}/CHANGELOG.md" | |
| if [ -f "${PACKAGE}/package-lock.json" ]; then | |
| git add "${PACKAGE}/package-lock.json" | |
| fi | |
| if [ -f "${PACKAGE}/bun.lock" ]; then | |
| git add "${PACKAGE}/bun.lock" | |
| fi | |
| if [ -f "${PACKAGE}/bun.lockb" ]; then | |
| git add "${PACKAGE}/bun.lockb" | |
| fi | |
| if git diff --cached --quiet; then | |
| echo "No changes to commit" | |
| exit 1 | |
| fi | |
| git commit -m "chore(${PACKAGE}): release v${NEW_VERSION}" | |
| - name: Resolve workspace dependencies | |
| working-directory: ${{ env.PACKAGE }} | |
| run: | | |
| # Get the version of @phala/cloud from js/package.json | |
| if grep -q '"@phala/cloud": "workspace:\*"' package.json; then | |
| JS_VERSION=$(node -e "console.log(require('../js/package.json').version)") | |
| echo "Resolving workspace:* to version $JS_VERSION" | |
| node -e " | |
| const fs = require('fs'); | |
| const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); | |
| if (pkg.dependencies && pkg.dependencies['@phala/cloud'] === 'workspace:*') { | |
| pkg.dependencies['@phala/cloud'] = '^$JS_VERSION'; | |
| fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); | |
| } | |
| " | |
| fi | |
| - name: Upgrade npm for trusted publishing | |
| run: | | |
| # Ensure npm 11.5.1 or later for OIDC trusted publishing support | |
| npm install -g npm@latest | |
| npm --version | |
| - name: Verify OIDC token and npm authentication | |
| run: | | |
| echo "π Checking OIDC token availability..." | |
| if [ -n "${ACTIONS_ID_TOKEN_REQUEST_URL}" ] && [ -n "${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" ]; then | |
| echo "β OIDC token environment variables are set" | |
| echo " ACTIONS_ID_TOKEN_REQUEST_URL: ${ACTIONS_ID_TOKEN_REQUEST_URL}" | |
| else | |
| echo "β OIDC token environment variables are NOT set" | |
| echo " This indicates that id-token: write permission may not be working" | |
| fi | |
| echo "" | |
| echo "π Checking npm whoami (should work with OIDC)..." | |
| if npm whoami 2>&1 | grep -q "npm ERR!"; then | |
| echo "β οΈ npm whoami failed (expected for OIDC - no pre-auth needed)" | |
| else | |
| echo "β npm authenticated as: $(npm whoami)" | |
| fi | |
| echo "" | |
| echo "π npm config:" | |
| npm config list | |
| echo "" | |
| echo "π GitHub Actions context:" | |
| echo " Repository: ${{ github.repository }}" | |
| echo " Workflow: ${{ github.workflow }}" | |
| echo " Run ID: ${{ github.run_id }}" | |
| echo " Actor: ${{ github.actor }}" | |
| - name: Publish to npm | |
| working-directory: ${{ env.PACKAGE }} | |
| run: | | |
| echo "π Publishing @phala/cloud..." | |
| echo "" | |
| echo "Package info:" | |
| cat package.json | grep -E '"name"|"version"' | |
| echo "" | |
| echo "π Publish command: npm publish --access public --tag $NPM_TAG" | |
| echo "" | |
| # Publish using OIDC authentication (npm Trusted Publishers) | |
| # Requires npm >= 11.5.1 and id-token: write permission | |
| # Provenance attestations are generated automatically | |
| npm publish --access public --tag "$NPM_TAG" --verbose 2>&1 | tee publish.log || { | |
| echo "" | |
| echo "β Publish failed!" | |
| echo "" | |
| echo "π Checking authentication method used by npm..." | |
| if grep -q "oidc" publish.log || grep -q "OIDC" publish.log; then | |
| echo " npm attempted to use OIDC authentication" | |
| elif grep -q "token" publish.log || grep -q "TOKEN" publish.log; then | |
| echo " npm attempted to use token authentication" | |
| fi | |
| echo "" | |
| echo "π Checking Trusted Publisher configuration..." | |
| echo " Expected configuration on npmjs.com:" | |
| echo " - Package: @phala/cloud" | |
| echo " - Provider: GitHub Actions" | |
| echo " - Owner: Phala-Network" | |
| echo " - Repository: phala-cloud" | |
| echo " - Workflow: release-npm.yml" | |
| echo " - Environment: (empty)" | |
| echo "" | |
| echo " Actual workflow context:" | |
| echo " - Repository: ${{ github.repository }}" | |
| echo " - Workflow: ${{ github.workflow }}" | |
| echo " - Workflow file: ${{ github.workflow_ref }}" | |
| exit 1 | |
| } | |
| rm -f publish.log | |
| - name: Create tag | |
| run: git tag "$TAG_NAME" | |
| - name: Push changes | |
| id: push | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| if [ "$SOURCE_REF" = "main" ]; then | |
| # Main branch has protection rules - create a release branch and PR | |
| RELEASE_BRANCH="release/${PACKAGE}-v${NEW_VERSION}" | |
| git checkout -b "$RELEASE_BRANCH" | |
| git push origin "$RELEASE_BRANCH" | |
| git push origin "$TAG_NAME" | |
| # Create PR to merge release branch back to main | |
| PR_URL=$(gh pr create \ | |
| --base main \ | |
| --head "$RELEASE_BRANCH" \ | |
| --title "chore(${PACKAGE}): release v${NEW_VERSION}" \ | |
| --body "Automated release PR for ${PACKAGE} v${NEW_VERSION}. Updates package.json and CHANGELOG.md. The package has already been published to npm.") | |
| echo "release_pr_url=$PR_URL" >> "$GITHUB_OUTPUT" | |
| echo "used_release_branch=true" >> "$GITHUB_OUTPUT" | |
| echo "release_branch=$RELEASE_BRANCH" >> "$GITHUB_OUTPUT" | |
| else | |
| # Feature branch - push directly | |
| git push origin HEAD:${SOURCE_REF} | |
| git push origin "$TAG_NAME" | |
| echo "used_release_branch=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Create GitHub release | |
| id: release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Build release body: changelog + install info | |
| { | |
| if [ -s "${PACKAGE}/RELEASE_NOTES.md" ]; then | |
| cat "${PACKAGE}/RELEASE_NOTES.md" | |
| else | |
| echo "Release ${PACKAGE} v${NEW_VERSION}" | |
| fi | |
| echo "" | |
| echo "---" | |
| echo "" | |
| echo "**npm**: [${{ steps.pkgmeta.outputs.npm_name }}@${NEW_VERSION}](${{ steps.pkgmeta.outputs.npm_url }})" | |
| echo "" | |
| echo "\`\`\`bash" | |
| echo "npm i -g ${{ steps.pkgmeta.outputs.npm_name }}@${NEW_VERSION}" | |
| echo "\`\`\`" | |
| } > release_body.md | |
| PRERELEASE_FLAG="" | |
| if [ -n "$PRERELEASE" ]; then | |
| PRERELEASE_FLAG="--prerelease" | |
| fi | |
| RELEASE_URL=$(gh release create "$TAG_NAME" \ | |
| --title "${{ steps.pkgmeta.outputs.npm_name }} v${NEW_VERSION}" \ | |
| --notes-file release_body.md \ | |
| $PRERELEASE_FLAG) | |
| echo "html_url=$RELEASE_URL" >> "$GITHUB_OUTPUT" | |
| - name: Comment success | |
| if: ${{ success() && env.ISSUE_NUMBER != '' }} | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; | |
| const fileList = `${{ steps.pack_info.outputs.file_list }}`.split('\n').slice(0, 15).join('\n'); | |
| const totalFiles = Number('${{ steps.pack_info.outputs.total_files }}'); | |
| const hasMore = totalFiles > 15; | |
| const usedReleaseBranch = '${{ steps.push.outputs.used_release_branch }}' === 'true'; | |
| const releasePrUrl = '${{ steps.push.outputs.release_pr_url }}'; | |
| const body = [ | |
| `π Release completed: \`${process.env.PACKAGE}\` v${process.env.NEW_VERSION}`, | |
| '', | |
| `- Branch: \`${process.env.SOURCE_REF}\``, | |
| `- npm: [${{ steps.pkgmeta.outputs.npm_name }}](${{ steps.pkgmeta.outputs.npm_url }})`, | |
| `- GitHub Release: [link](${{ steps.release.outputs.html_url }})`, | |
| `- Workflow logs: ${runUrl}`, | |
| ]; | |
| if (usedReleaseBranch && releasePrUrl) { | |
| body.push(''); | |
| body.push(`> β οΈ **Action Required**: Please merge the [release PR](${releasePrUrl}) to update \`main\` branch with version changes.`); | |
| } | |
| body.push( | |
| '', | |
| '### π¦ Package Info', | |
| `- Package size: **${{ steps.pack_info.outputs.package_size }}**`, | |
| `- Unpacked size: **${{ steps.pack_info.outputs.unpacked_size }}**`, | |
| `- Total files: **${{ steps.pack_info.outputs.total_files }}**`, | |
| '', | |
| '<details>', | |
| `<summary>π Files included${hasMore ? ' (showing first 15)' : ''}</summary>`, | |
| '', | |
| '```', | |
| fileList, | |
| hasMore ? `... and ${totalFiles - 15} more files` : '', | |
| '```', | |
| '</details>' | |
| ); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: Number(process.env.ISSUE_NUMBER), | |
| body: body.join('\n') | |
| }); | |
| - name: Comment failure | |
| if: ${{ failure() && env.ISSUE_NUMBER != '' }} | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; | |
| const actor = process.env.REQUESTED_BY ? `@${process.env.REQUESTED_BY}` : 'Requester'; | |
| const version = process.env.NEW_VERSION || 'unknown version'; | |
| const body = [ | |
| `β ${actor} release failed: \`${process.env.PACKAGE}\` ${version}`, | |
| '', | |
| `Branch: \`${process.env.SOURCE_REF}\``, | |
| `Please review the workflow logs: ${runUrl}` | |
| ].join('\n'); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: Number(process.env.ISSUE_NUMBER), | |
| body | |
| }); |