ci: Call Cloud DB populate workflow from actions (#26808)

This commit is contained in:
Matsu 2026-03-10 15:24:06 +02:00 committed by GitHub
parent 9a1b434f7a
commit adb9b26cb1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 223 additions and 2 deletions

View File

@ -0,0 +1,46 @@
import { ensureEnvVar, sh, writeGithubOutput } from './github-helpers.mjs';
function determineReleaseVersionChanges() {
const previousVersion = ensureEnvVar('PREVIOUS_VERSION_TAG');
const releaseVersion = ensureEnvVar('RELEASE_VERSION_TAG');
const log = sh('git', [
'--no-pager',
'log',
'--format="%s (%h)"',
`${previousVersion}..${releaseVersion}`,
]);
writeGithubOutput({
has_node_enhancements: hasNodeEnhancements(log),
has_core_changes: hasCoreChanges(log),
});
}
/**
* Matches commit messages with
*
* fix(nodes)
* fix(xyz Node)
* feat(nodes)
* feat(xyz Node)
*
* @param {string} log
*/
export function hasNodeEnhancements(log) {
return /(fix|feat)\((.*Node|nodes)\)/.test(log);
}
/**
* Matches commit messages with feat(core) or feat(editor)
*
* @param {string} log
*/
export function hasCoreChanges(log) {
return /feat\((core|editor)\)/.test(log);
}
// only run when executed directly, not when imported by tests
if (import.meta.url === `file://${process.argv[1]}`) {
determineReleaseVersionChanges();
}

View File

@ -0,0 +1,47 @@
import { describe, it, mock, before } from 'node:test';
import assert from 'node:assert/strict';
/**
* Run these tests by running
*
* node --test --experimental-test-module-mocks ./.github/scripts/determine-release-version-changes.test.mjs
* */
// mock.module must be called before the module under test is imported,
// because static imports are hoisted and resolve before any code runs.
mock.module('./github-helpers.mjs', {
namedExports: {
ensureEnvVar: () => {}, // no-op
sh: () => {}, // no-op
writeGithubOutput: () => {}, // no-op
},
});
let hasNodeEnhancements, hasCoreChanges;
before(async () => {
({ hasNodeEnhancements, hasCoreChanges } = await import(
'./determine-release-version-changes.mjs'
));
});
describe('Determine release version changes', () => {
it('Matches nodes feature', () => {
assert.ok(hasNodeEnhancements('feat(nodes): Added a utility for node'));
});
it('Matches nodes fix', () => {
assert.ok(hasNodeEnhancements('fix(nodes): Fix said utility'));
});
it('Matches named node feature', () => {
assert.ok(hasNodeEnhancements('feat(Github Actions Node): Add ability to call webhooks'));
});
it('Matches named node fix', () => {
assert.ok(hasNodeEnhancements('fix(OpenAI Node): Allow credentials to pass through'));
});
it('Matches core changes', () => {
assert.ok(hasCoreChanges('feat(core): Add cli flag'));
});
it('Matches editor changes', () => {
assert.ok(hasCoreChanges('feat(editor): Add button'));
});
});

View File

@ -56,7 +56,10 @@ export function determineTrack(packageVersion) {
tag: /** @type {import('./github-helpers.mjs').ReleaseVersion} */ (`n8n@${packageVersion}`),
});
const previousVersion = trackToReleaseMap[track]?.version;
const output = {
previous_version: previousVersion,
version: packageVersion,
track,
bump,
@ -67,7 +70,7 @@ export function determineTrack(packageVersion) {
writeGithubOutput(output);
console.log(
`Determined track info: track=${track}, version=${packageVersion}, new_stable_version=${newStable}, release_type=${releaseType}, rc_branch=${rc_branch}`,
`Determined track info: track=${track}, version=${packageVersion}, previous_version=${previousVersion}, new_stable_version=${newStable}, release_type=${releaseType}, rc_branch=${rc_branch}`,
);
return output;

View File

@ -37,6 +37,7 @@ describe('determine-tracks', () => {
assert.equal(output.track, 'stable');
assert.equal(output.version, '2.9.3');
assert.equal(output.previous_version, '2.9.2');
assert.equal(output.bump, 'patch');
assert.equal(output.new_stable_version, null);
assert.equal(output.release_type, 'stable');
@ -48,6 +49,7 @@ describe('determine-tracks', () => {
assert.equal(output.track, 'beta');
assert.equal(output.version, '2.10.2');
assert.equal(output.previous_version, '2.10.1');
assert.equal(output.bump, 'patch');
assert.equal(output.new_stable_version, null);
assert.equal(output.release_type, 'stable');
@ -60,6 +62,7 @@ describe('determine-tracks', () => {
assert.equal(output.track, 'stable');
assert.equal(output.version, '2.9.4');
assert.equal(output.previous_version, '2.9.2');
assert.equal(output.bump, 'patch');
assert.equal(output.new_stable_version, null);
assert.equal(output.release_type, 'stable');
@ -81,6 +84,7 @@ describe('determine-tracks', () => {
assert.equal(output.track, 'beta');
assert.equal(output.version, '2.11.0');
assert.equal(output.previous_version, '2.10.1');
assert.equal(output.bump, 'minor');
assert.equal(output.new_stable_version, '2.10.1');
assert.equal(output.release_type, 'stable');
@ -92,6 +96,7 @@ describe('determine-tracks', () => {
assert.equal(output.track, 'beta');
assert.equal(output.version, '2.10.2-rc.1');
assert.equal(output.previous_version, '2.10.1');
assert.equal(output.bump, 'patch');
assert.equal(output.new_stable_version, null);
assert.equal(output.release_type, 'rc');

View File

@ -205,7 +205,7 @@ export function trySh(cmd, args, opts = {}) {
/**
* Append outputs to GITHUB_OUTPUT if available.
*
* @param {Record<string, string>} obj
* @param {Record<string, string | boolean>} obj
*/
export function writeGithubOutput(obj) {
const path = process.env.GITHUB_OUTPUT;

View File

@ -0,0 +1,32 @@
import { ensureEnvVar } from './github-helpers.mjs';
async function populateCloudDatabases() {
const payload = ensureEnvVar('PAYLOAD');
const webhookData = ensureEnvVar('N8N_POPULATE_CLOUD_WEBHOOK_DATA');
const { user, secret, url } = JSON.parse(webhookData);
console.log('Payload: ', JSON.parse(payload));
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Basic ' + Buffer.from(`${user}:${secret}`).toString('base64'),
},
body: payload,
});
const status = response.status;
console.log('Webhook call returned status ' + status);
if (status !== 200) {
const body = await response.text();
throw new Error(`Webhook call failed:\n\n ${body}`);
}
}
// only run when executed directly, not when imported by tests
if (import.meta.url === `file://${process.argv[1]}`) {
populateCloudDatabases();
}

View File

@ -0,0 +1,72 @@
name: 'Release: Populate cloud with releases'
run-name: 'Populate cloud with version n8n@${{ inputs.version }}'
on:
workflow_dispatch:
inputs:
previous-version:
description: 'The previous release version (e.g. 2.10.2)'
required: true
type: string
version:
description: 'The release version (e.g. 2.11.0)'
required: true
type: string
experimental:
description: 'If publishing experimental version'
type: boolean
default: false
workflow_call:
inputs:
previous-version:
description: 'The previous release version (e.g. 2.10.2)'
required: true
type: string
version:
description: 'The release version (e.g. 2.11.0)'
required: true
type: string
experimental:
description: 'If publishing experimental version'
type: boolean
default: false
jobs:
determine-changes:
runs-on: ubuntu-slim
environment: release
outputs:
has_node_enhancements: ${{ steps.get-changes.outputs.has_node_enhancements }}
has_core_changes: ${{ steps.get-changes.outputs.has_core_changes }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Setup Node.js
uses: ./.github/actions/setup-nodejs
with:
build-command: ''
install-command: npm install --prefix=.github/scripts --no-package-lock
- name: Extract changes
id: get-changes
env:
PREVIOUS_VERSION_TAG: 'n8n@${{ inputs.previous-version }}'
RELEASE_VERSION_TAG: 'n8n@${{ inputs.version }}'
run: node ./.github/scripts/determine-release-version-changes.mjs
- name: Populate databases
id: populate-databases
env:
N8N_POPULATE_CLOUD_WEBHOOK_DATA: ${{ secrets.N8N_POPULATE_CLOUD_WEBHOOK_DATA }}
PAYLOAD: |
{
"target_version_to_update": "${{ inputs.version }}",
"has_node_enhancements": ${{ steps.get-changes.outputs.has_node_enhancements }},
"has_core_changes": ${{ steps.get-changes.outputs.has_core_changes }},
"has_breaking_change": false,
"is_experimental": ${{ inputs.experimental }}
}
run: node ./.github/scripts/populate-cloud-databases.mjs

View File

@ -7,6 +7,10 @@ on:
description: 'Release track acquired from determine-version-info. (e.g. stable, beta)'
required: true
type: string
previous_version:
description: 'Previous release version acquired from determine-version-info. (e.g. 2.9.2, 1.123.22)'
required: true
type: string
version:
description: 'Release version acquired from determine-version-info. (e.g. 2.9.3, 1.123.23)'
required: true
@ -51,3 +55,12 @@ jobs:
inputs.release_type != 'rc'
uses: ./.github/workflows/util-ensure-release-candidate-branches.yml
secrets: inherit
populate-cloud-with-releases:
name: 'Populate cloud database with releases'
uses: ./.github/workflows/release-populate-cloud-with-releases.yml
with:
previous-version: ${{ inputs.previous_version }}
version: ${{ inputs.version }}
experimental: ${{ inputs.release_type == 'rc' }}
secrets: inherit

View File

@ -14,6 +14,7 @@ jobs:
if: github.event.pull_request.merged == true
outputs:
track: ${{ steps.determine-info.outputs.track }}
previous_version: ${{ steps.determine-info.outputs.previous_version }}
version: ${{ steps.determine-info.outputs.version }}
bump: ${{ steps.determine-info.outputs.bump }}
new_stable_version: ${{ steps.determine-info.outputs.new_stable_version }}
@ -192,6 +193,7 @@ jobs:
uses: ./.github/workflows/release-publish-post-release.yml
with:
track: ${{ needs.determine-version-info.outputs.track }}
previous_version: ${{ needs.determine-version-info.outputs.previous_version }}
version: ${{ needs.determine-version-info.outputs.version }}
bump: ${{ needs.determine-version-info.outputs.bump }}
new_stable_version: ${{ needs.determine-version-info.outputs.new_stable_version }}

1
.gitignore vendored
View File

@ -40,6 +40,7 @@ compiled
docker-build-manifest.json
packages/cli/src/modules/my-feature
.secrets
act-event.json
packages/testing/**/.cursor/rules/
.venv
.ruff_cache