refactor(PLATENG-800): replace platform-sdk-fetch with integration-sdk-http-client #42
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: SDK Monorepo Canary Release | |
| on: | |
| issue_comment: | |
| types: | |
| - created | |
| jobs: | |
| # Gate job to check authorization before running the main workflow | |
| check-authorization: | |
| name: Check Authorization | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/canary-release') }} | |
| outputs: | |
| is-authorized: ${{ steps.check.outputs.authorized }} | |
| steps: | |
| - name: Check if user is authorized | |
| id: check | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const authorAssociation = context.payload.comment.author_association; | |
| const authorizedRoles = ['OWNER', 'MEMBER', 'COLLABORATOR']; | |
| const isAuthorized = authorizedRoles.includes(authorAssociation); | |
| console.log(`Author: ${context.payload.comment.user.login}`); | |
| console.log(`Association: ${authorAssociation}`); | |
| console.log(`Authorized: ${isAuthorized}`); | |
| core.setOutput('authorized', isAuthorized ? 'true' : 'false'); | |
| if (!isAuthorized) { | |
| await github.rest.reactions.createForIssueComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: context.payload.comment.id, | |
| content: '-1', | |
| }); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `⛔ **Unauthorized**: Only organization members can trigger canary releases.\n\n` + | |
| `User \`${context.payload.comment.user.login}\` has association: \`${authorAssociation}\`` | |
| }); | |
| } | |
| canary-release: | |
| name: Canary Release | |
| runs-on: ubuntu-latest | |
| needs: check-authorization | |
| if: ${{ needs.check-authorization.outputs.is-authorized == 'true' }} | |
| # Environment with protection rules - configure in GitHub Settings > Environments | |
| environment: canary-publish | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| id-token: write | |
| steps: | |
| - name: Add reaction to comment | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.reactions.createForIssueComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: context.payload.comment.id, | |
| content: 'eyes', | |
| }); | |
| - name: Post starting comment | |
| id: start-comment | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const comment = await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `🚀 Canary release workflow has been triggered.\n\nYou can follow the progress [here](${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}).` | |
| }); | |
| return comment.data.id; | |
| result-encoding: string | |
| - name: Checkout PR | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: refs/pull/${{ github.event.issue.number }}/head | |
| fetch-depth: 0 | |
| token: ${{ secrets.AUTO_GITHUB_PAT_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Configure npm authentication | |
| run: | | |
| echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" >> .npmrc | |
| - name: Install dependencies | |
| run: npm ci --include=optional | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} | |
| - name: Configure git | |
| run: | | |
| git config --global user.email "automation@jupiterone.com" | |
| git config --global user.name "Automation" | |
| - name: Detect affected packages | |
| id: changed | |
| run: | | |
| AFFECTED=$(npx nx show projects --affected --base=origin/main --json 2>/dev/null || echo "[]") | |
| echo "Affected packages: $AFFECTED" | |
| echo "packages=$AFFECTED" >> $GITHUB_OUTPUT | |
| if [ "$AFFECTED" = "[]" ] || [ -z "$AFFECTED" ]; then | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Bump canary versions | |
| if: steps.changed.outputs.has_changes == 'true' | |
| run: | | |
| node <<'SCRIPT' | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const preid = process.env.PRERELEASE_ID; | |
| const packagesDir = 'packages'; | |
| const dirs = fs.readdirSync(packagesDir).filter(d => | |
| fs.existsSync(path.join(packagesDir, d, 'package.json')) | |
| ); | |
| // Load all packages | |
| const packages = new Map(); | |
| for (const dir of dirs) { | |
| const pkgPath = path.join(packagesDir, dir, 'package.json'); | |
| const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); | |
| packages.set(pkg.name, { dir, pkg, pkgPath }); | |
| } | |
| // Bump non-private packages to canary version | |
| const bumped = new Map(); | |
| for (const [name, entry] of packages) { | |
| if (entry.pkg.private) { | |
| console.log(`Skipping private: ${name}`); | |
| continue; | |
| } | |
| const canaryVersion = `${entry.pkg.version}-${preid}.0`; | |
| entry.pkg.version = canaryVersion; | |
| bumped.set(name, canaryVersion); | |
| console.log(`${name} -> ${canaryVersion}`); | |
| } | |
| // Update internal cross-references | |
| for (const [, entry] of packages) { | |
| let changed = false; | |
| for (const depType of ['dependencies', 'devDependencies', 'peerDependencies']) { | |
| if (!entry.pkg[depType]) continue; | |
| for (const depName of Object.keys(entry.pkg[depType])) { | |
| if (bumped.has(depName)) { | |
| entry.pkg[depType][depName] = bumped.get(depName); | |
| changed = true; | |
| } | |
| } | |
| } | |
| if (changed || bumped.has(entry.pkg.name)) { | |
| fs.writeFileSync(entry.pkgPath, JSON.stringify(entry.pkg, null, 2) + '\n'); | |
| } | |
| } | |
| SCRIPT | |
| env: | |
| PRERELEASE_ID: canary-${{ github.event.issue.number }}-${{ github.run_id }} | |
| - name: Build packages | |
| if: steps.changed.outputs.has_changes == 'true' | |
| run: npx nx run-many -t build:dist | |
| - name: Publish canary versions | |
| id: publish | |
| if: steps.changed.outputs.has_changes == 'true' | |
| run: npx nx release publish --tag canary | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} | |
| NPM_CONFIG_REGISTRY: https://registry.npmjs.org | |
| - name: Comment with published versions | |
| if: steps.changed.outputs.has_changes == 'true' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| // Read all non-private package versions | |
| let versionsList = []; | |
| let installCommands = []; | |
| const packagesDir = path.join(process.env.GITHUB_WORKSPACE, 'packages'); | |
| const dirs = fs.readdirSync(packagesDir); | |
| for (const dir of dirs) { | |
| const pkgPath = path.join(packagesDir, dir, 'package.json'); | |
| if (fs.existsSync(pkgPath)) { | |
| const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); | |
| if (!pkg.private && pkg.version.includes('canary')) { | |
| versionsList.push(`- \`${pkg.name}@${pkg.version}\``); | |
| installCommands.push(`npm install ${pkg.name}@${pkg.version}`); | |
| } | |
| } | |
| } | |
| const versionsText = versionsList.join('\n'); | |
| const installText = installCommands.join('\n'); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `✅ **Canary release published successfully!**\n\n**Published packages:**\n${versionsText}\n\n**Install with:**\n\`\`\`bash\n${installText}\n\`\`\`` | |
| }); | |
| - name: Comment if no changes | |
| if: steps.changed.outputs.has_changes == 'false' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `⚠️ **No packages to publish.**\n\nNo changes detected compared to main branch.` | |
| }); | |
| - name: Add success reaction | |
| if: success() | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.reactions.createForIssueComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: context.payload.comment.id, | |
| content: 'rocket', | |
| }); | |
| - name: Add failure reaction | |
| if: failure() | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.reactions.createForIssueComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: context.payload.comment.id, | |
| content: 'confused', | |
| }); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `❌ **Canary release failed.**\n\nCheck the [workflow run](${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}) for details.` | |
| }); |