Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 81 additions & 40 deletions .github/workflows/canary.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ jobs:
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:
Expand All @@ -106,72 +110,109 @@ jobs:
git config --global user.email "automation@jupiterone.com"
git config --global user.name "Automation"

- name: Get changed packages
- name: Detect affected packages
id: changed
run: |
# Get list of packages changed since main (compact JSON for single-line output)
CHANGED=$(npx lerna changed --json 2>/dev/null | jq -c '.' || echo "[]")
echo "Changed packages: $CHANGED"

# Output as single line (no heredoc needed for compact JSON)
echo "packages=$CHANGED" >> $GITHUB_OUTPUT
AFFECTED=$(npx nx show projects --affected --base=origin/main --json 2>/dev/null || echo "[]")
echo "Affected packages: $AFFECTED"
echo "packages=$AFFECTED" >> $GITHUB_OUTPUT

# Check if there are any changed packages
if [ "$CHANGED" = "[]" ]; then
if [ "$AFFECTED" = "[]" ] || [ -z "$AFFECTED" ]; then
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "has_changes=true" >> $GITHUB_OUTPUT
fi

- name: Build packages
if: steps.changed.outputs.has_changes == 'true'
run: npm run build:dist

- name: Publish canary versions
id: publish
- name: Bump canary versions
if: steps.changed.outputs.has_changes == 'true'
run: |
PRERELEASE_ID="canary-${{ github.event.issue.number }}-${{ github.run_id }}"
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 });
}

# Version bump with canary prerelease
npx lerna version prerelease --preid "$PRERELEASE_ID" --no-git-tag-version --no-push --yes
// 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}`);
}

# Commit version changes locally to satisfy lerna publish
# These changes won't be pushed back to the PR
# Only stage lerna-modified files (package.json, lerna.json, package-lock.json)
git add lerna.json package-lock.json packages/*/package.json
git commit -m "chore: canary version bump [skip ci]" --no-verify
// 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 }}

# Publish with canary tag
npx lerna publish from-package --dist-tag canary --yes 2>&1 | tee publish-output.txt
- name: Build packages
if: steps.changed.outputs.has_changes == 'true'
run: npx nx run-many -t build:dist

# Extract published versions
PUBLISHED=$(grep -E "Successfully published" publish-output.txt || echo "")
echo "published<<EOF" >> $GITHUB_OUTPUT
echo "$PUBLISHED" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- 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 }}
GH_TOKEN: ${{ secrets.AUTO_GITHUB_PAT_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 packages = JSON.parse('${{ steps.changed.outputs.packages }}');
const fs = require('fs');
const path = require('path');

// Build versions list and install commands from package.json files
// Read all non-private package versions
let versionsList = [];
let installCommands = [];

for (const pkg of packages) {
const pkgPath = pkg.location.startsWith(process.env.GITHUB_WORKSPACE)
? pkg.location
: `${process.env.GITHUB_WORKSPACE}/${pkg.location}`;
const pkgJson = require(`${pkgPath}/package.json`);
versionsList.push(`- \`${pkg.name}@${pkgJson.version}\``);
installCommands.push(`npm install ${pkg.name}@${pkgJson.version}`);
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');
Expand Down