fix: Replace reusable workflow with standalone canary release#1189
fix: Replace reusable workflow with standalone canary release#1189tokio-on-jupiter merged 4 commits intomainfrom
Conversation
The sdk repo is public and cannot access private reusable workflows from github-internal. This replaces the reusable workflow reference with a standalone implementation that works for public repositories. Uses Lerna for: - Detecting changed packages - Bumping versions with canary prerelease - Publishing with canary dist-tag
There was a problem hiding this comment.
Pull request overview
This PR replaces a private reusable workflow reference with a standalone canary release workflow implementation. The previous implementation referenced a private workflow from jupiterone/github-internal which is inaccessible from this public repository.
Changes:
- Replaced reusable workflow with inline canary release implementation
- Added Lerna-based package detection, versioning, and publishing steps
- Implemented GitHub reactions and comments for workflow status feedback
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.github/workflows/canary.yaml
Outdated
| PREID="canary-${{ github.event.issue.number }}-${{ github.run_attempt }}" | ||
|
|
||
| # Version bump with canary prerelease | ||
| npx lerna version prerelease --preid "$PREID" --no-git-tag-version --no-push --yes |
There was a problem hiding this comment.
The variable PREID uses an abbreviation that may not be immediately clear to all developers. Consider renaming to PRERELEASE_ID for better clarity.
| PREID="canary-${{ github.event.issue.number }}-${{ github.run_attempt }}" | |
| # Version bump with canary prerelease | |
| npx lerna version prerelease --preid "$PREID" --no-git-tag-version --no-push --yes | |
| PRERELEASE_ID="canary-${{ github.event.issue.number }}-${{ github.run_attempt }}" | |
| # Version bump with canary prerelease | |
| npx lerna version prerelease --preid "$PRERELEASE_ID" --no-git-tag-version --no-push --yes |
.github/workflows/canary.yaml
Outdated
| const packages = JSON.parse('${{ steps.changed.outputs.packages }}'); | ||
|
|
||
| let installCommands = packages.map(pkg => { | ||
| const pkgJson = require(`${process.env.GITHUB_WORKSPACE}/${pkg.location.replace(process.env.GITHUB_WORKSPACE + '/', '')}/package.json`); |
There was a problem hiding this comment.
The path construction is overly complex with redundant GITHUB_WORKSPACE replacement. Since pkg.location likely already contains the full path or is relative to GITHUB_WORKSPACE, simplify by using pkg.location directly or just removing the workspace prefix once.
| const pkgJson = require(`${process.env.GITHUB_WORKSPACE}/${pkg.location.replace(process.env.GITHUB_WORKSPACE + '/', '')}/package.json`); | |
| const pkgPath = pkg.location.startsWith(process.env.GITHUB_WORKSPACE) | |
| ? pkg.location | |
| : `${process.env.GITHUB_WORKSPACE}/${pkg.location}`; | |
| const pkgJson = require(`${pkgPath}/package.json`); |
| - name: Configure npm for JupiterOne packages | ||
| run: | | ||
| echo "@jupiterone:registry=https://npm.pkg.github.com" >> .npmrc | ||
| echo "//npm.pkg.github.com/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" >> .npmrc |
There was a problem hiding this comment.
The same NPM_AUTH_TOKEN is being used for both GitHub Packages and the public npm registry. This could be a security concern if the token has broader permissions than needed. Consider using separate tokens (NPM_AUTH_TOKEN for npm and GITHUB_TOKEN or a dedicated token for GitHub Packages) to follow the principle of least privilege.
| echo "//npm.pkg.github.com/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" >> .npmrc | |
| echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> .npmrc |
- Rename PREID to PRERELEASE_ID for better clarity - Simplify path construction in package.json lookup Note: Intentionally keeping NPM_AUTH_TOKEN for GitHub Packages as GITHUB_TOKEN lacks permissions for private @JupiterOne packages
Security improvements for public repository canary releases: 1. Actor validation gate job: - Only OWNER, MEMBER, or COLLABORATOR can trigger releases - Unauthorized attempts get thumbs-down reaction + explanatory comment - Logs author association for audit trail 2. Environment protection: - Adds 'canary-publish' environment requirement - Allows configuring required reviewers in GitHub Settings - Secrets only available when environment rules pass Setup required: - Go to GitHub Settings > Environments - Create 'canary-publish' environment - Add required reviewers (optional but recommended) - Environment protection rules will gate secret access
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - name: Configure npm for JupiterOne packages | ||
| run: | | ||
| echo "@jupiterone:registry=https://npm.pkg.github.com" >> .npmrc | ||
| echo "//npm.pkg.github.com/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" >> .npmrc |
There was a problem hiding this comment.
The same NPM_AUTH_TOKEN is being used for both GitHub Packages registry and the public npm registry. These should typically be different tokens - one for GitHub Packages (@JupiterOne scope) and one for npmjs.org. Using the same token could be a security risk if it grants broader permissions than necessary.
| echo "//npm.pkg.github.com/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" >> .npmrc | |
| echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_PACKAGES_NPM_TOKEN }}" >> .npmrc |
.github/workflows/canary.yaml
Outdated
| VERSIONS="" | ||
| for pkg in $(echo '${{ steps.changed.outputs.packages }}' | jq -r '.[].name'); do | ||
| PKG_PATH=$(echo '${{ steps.changed.outputs.packages }}' | jq -r ".[] | select(.name == \"$pkg\") | .location") | ||
| VERSION=$(cat "$PKG_PATH/package.json" | jq -r '.version') |
There was a problem hiding this comment.
Using 'cat' and piping to jq is unnecessary. Use 'jq -r .version "$PKG_PATH/package.json"' instead for better performance and clarity.
| VERSION=$(cat "$PKG_PATH/package.json" | jq -r '.version') | |
| VERSION=$(jq -r '.version' "$PKG_PATH/package.json") |
Addresses Copilot review feedback - jq can read files directly without needing cat, improving performance and clarity.
Summary
The sdk repo is public and cannot access private reusable workflows from
github-internal. The previous PR #1187 added a reusable workflow reference that fails with "workflow was not found" error.This PR replaces the reusable workflow reference with a standalone implementation adapted for this Lerna monorepo, with security hardening for public repositories.
Security Features
1. Actor Validation (Immediate Protection)
OWNER,MEMBER, orCOLLABORATORcan trigger/canary-release2. Environment Protection (Configurable)
canary-publishenvironmentSetup Required After Merge
canary-publishmainChanges
author_associationcanary-publishenvironment for secret protectionTest Plan
canary-publishenvironment in GitHub Settings/canary-releaseon PR feat(PLATENG-800): Replace @lifeomic/alpha with @jupiterone/platform-sdk-fetch #1188 to test the workflowRelated