Skip to content

refactor(PLATENG-800): replace platform-sdk-fetch with integration-sdk-http-client #42

refactor(PLATENG-800): replace platform-sdk-fetch with integration-sdk-http-client

refactor(PLATENG-800): replace platform-sdk-fetch with integration-sdk-http-client #42

Workflow file for this run

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.`
});