This commit is contained in:
Justin Dalrymple 2026-01-17 18:01:44 -05:00
parent fb356de2af
commit a84072bffc
6 changed files with 84 additions and 74 deletions

View File

@ -467,11 +467,11 @@ jobs:
- run:
name: Check for canary release
command: |
echo "$CIRCLE_PR_NUMBER"
echo "$CIRCLE_PULL_REQUEST"
if [[ -n "$CIRCLE_PULL_REQUEST" ]]; then
export PR_NUMBER=$(echo $CIRCLE_PULL_REQUEST | sed 's/.*\/pull\///')
if [[ -n "$PR_NUMBER" ]]; then
# Check if PR has release:canary label
if ./scripts/check-release-label.sh $CIRCLE_PR_NUMBER; then
if node scripts/check-release-label.mjs $PR_NUMBER; then
echo "Proceeding with canary release"
yarn release:canary
else
@ -496,7 +496,10 @@ jobs:
git checkout $CIRCLE_BRANCH
- run:
name: Release production
command: yarn release
command: |
export PR_NUMBER=$(echo $CIRCLE_PULL_REQUEST | sed 's/.*\/pull\///')
yarn release
# ====================
# WORKFLOWS

View File

@ -0,0 +1,39 @@
#!/usr/bin/env node
/**
* Check if PR has release:canary label
* Usage:
* node scripts/check-release-label.mjs <PR_NUMBER>
* node scripts/check-release-label.mjs # Uses environment variables
* Exit code: 0 if label found, 1 if not found
*/
import { fetchPRData } from './github-api.mjs';
const prNumber = process.argv[2] || process.env.CIRCLE_PR_NUMBER || process.env.PR_NUMBER;
if (!prNumber) {
console.error('No PR number provided');
process.exit(1);
}
async function checkReleaseLabel() {
try {
const prData = await fetchPRData(prNumber);
const labels = prData.labels.map(label => label.name);
console.log(`PR #${prNumber} labels: ${labels.join(', ')}`);
if (labels.includes('release:canary')) {
console.log('✅ Found release:canary label');
process.exit(0);
} else {
console.log('❌ No release:canary label found');
process.exit(1);
}
} catch (error) {
console.error('Error checking label:', error.message);
process.exit(1);
}
}
checkReleaseLabel();

View File

@ -1,41 +0,0 @@
#!/bin/bash
# Check if PR has release:canary label
# Usage: ./scripts/check-release-label.sh <PR_NUMBER>
# Exit code: 0 if label found, 1 if not found
PR_NUMBER=${1:-$CIRCLE_PR_NUMBER}
if [[ -z "$PR_NUMBER" ]]; then
echo "No PR number provided"
exit 1
fi
if [[ -z "$GITHUB_TOKEN" ]]; then
echo "GITHUB_TOKEN environment variable required"
exit 1
fi
echo "Checking PR #$PR_NUMBER for release:canary label..."
# Fetch PR labels from GitHub API
labels=$(curl -s \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-H "User-Agent: gitbeaker-release-checker" \
"https://api.github.com/repos/jdalrymple/gitbeaker/pulls/$PR_NUMBER" | \
jq -r '.labels[].name' 2>/dev/null)
if [[ $? -ne 0 ]]; then
echo "❌ Failed to fetch PR labels"
exit 1
fi
echo "PR #$PR_NUMBER labels: $(echo "$labels" | tr '\n' ', ' | sed 's/, $//')"
if echo "$labels" | grep -q "^release:canary$"; then
echo "✅ Found release:canary label"
exit 0
else
echo "❌ No release:canary label found"
exit 1
fi

View File

@ -1,6 +1,7 @@
#!/usr/bin/env node
import { writeFileSync, existsSync, mkdirSync } from 'fs';
import { execSync } from 'child_process';
import { fetchPRData } from './github-api.mjs';
const labelToChangeType = {
breaking: 'major',
@ -43,41 +44,16 @@ function generateChangesetYaml(packageNames, changeType) {
}
async function generateChangesetFromPR() {
const prNumber = process.env.CIRCLE_PR_NUMBER;
const repoUrl = process.env.CIRCLE_REPOSITORY_URL;
const prNumber = process.env.PR_NUMBER;
if (!prNumber) {
console.log('No PR number found in environment, skipping changeset generation');
return;
}
// Extract owner/repo from URL
const match = repoUrl.match(/github\.com[/:]([\w-]+)\/([\w-]+)/);
if (!match) {
console.error('Could not parse repository URL:', repoUrl);
return;
}
const [, owner, repo] = match;
try {
// Fetch PR data from GitHub API
const response = await fetch(
`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}`,
{
headers: {
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
Accept: 'application/vnd.github.v3+json',
'User-Agent': 'gitbeaker-changeset-generator',
},
},
);
if (!response.ok) {
console.error(`GitHub API error: ${response.status} ${response.statusText}`);
return;
}
const prData = await response.json();
const prData = await fetchPRData(prNumber);
// Get labels
const labels = prData.labels.map((label) => label.name);

33
scripts/github-api.mjs Normal file
View File

@ -0,0 +1,33 @@
/**
* Shared GitHub API utilities
*/
/**
* Fetch PR data from GitHub API
* @param {string} prNumber - The PR number
* @returns {Promise<Object>} PR data from GitHub API
*/
export async function fetchPRData(prNumber) {
const repoUrl = process.env.CIRCLE_REPOSITORY_URL || 'https://github.com/jdalrymple/gitbeaker';
// Extract owner/repo from URL
const match = repoUrl.match(/github\.com[/:]([\w-]+)\/([\w-]+)/);
if (!match) {
throw new Error(`Could not parse repository URL: ${repoUrl}`);
}
const [, owner, repo] = match;
const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}`, {
headers: {
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`,
'Accept': 'application/vnd.github.v3+json',
'User-Agent': 'gitbeaker-api-client'
}
});
if (!response.ok) {
throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);
}
return response.json();
}

View File

@ -30,7 +30,7 @@ async function release() {
// Generate changeset from PR labels
// Adds limitation to only release from PRs for now
let prNumber = process.env.CIRCLE_PR_NUMBER;
let prNumber = process.env.PR_NUMBER;
if (!prNumber) {
logStep('No PR number found - skipping release');