mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-12 16:10:30 +02:00
ci: Create github releases from mjs scripts (#27121)
This commit is contained in:
parent
8995c25512
commit
927b7bc818
81
.github/scripts/create-github-release.mjs
vendored
Normal file
81
.github/scripts/create-github-release.mjs
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
import {
|
||||||
|
deleteRelease,
|
||||||
|
ensureEnvVar,
|
||||||
|
getExistingRelease,
|
||||||
|
initGithub,
|
||||||
|
isReleaseTrack,
|
||||||
|
writeGithubOutput,
|
||||||
|
} from './github-helpers.mjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates release in GitHub.
|
||||||
|
*
|
||||||
|
* Required env variables:
|
||||||
|
* - RELEASE_TAG - Release tag on git e.g. n8n@2.13.0
|
||||||
|
* - BODY - Body of the release. Contains release notes etc.
|
||||||
|
* - IS_PRE_RELEASE - If releasing in pre-release. Currently only for beta track.
|
||||||
|
* - MAKE_LATEST - If released version should be marked as latest on GitHub
|
||||||
|
* - COMMIT - Commitish for release to point to
|
||||||
|
*
|
||||||
|
* Optional env variables:
|
||||||
|
* - ADDITIONAL_TAGS - Comma-separated list of additional tags to release under e.g. beta
|
||||||
|
*
|
||||||
|
* GitHub variables
|
||||||
|
* - GITHUB_TOKEN - Used to authenticate to octokit - Can be overwritten for privileged access
|
||||||
|
* - GITHUB_REPOSITORY - Used to determine target repository
|
||||||
|
* */
|
||||||
|
async function createGitHubRelease() {
|
||||||
|
const RELEASE_TAG = ensureEnvVar('RELEASE_TAG');
|
||||||
|
const ADDITIONAL_TAGS = process.env.ADDITIONAL_TAGS ?? '';
|
||||||
|
const BODY = ensureEnvVar('BODY');
|
||||||
|
const IS_PRE_RELEASE = ensureEnvVar('IS_PRE_RELEASE');
|
||||||
|
const MAKE_LATEST = ensureEnvVar('MAKE_LATEST');
|
||||||
|
const COMMIT = ensureEnvVar('COMMIT');
|
||||||
|
|
||||||
|
const { octokit, owner, repo } = initGithub();
|
||||||
|
|
||||||
|
const allTags = [
|
||||||
|
RELEASE_TAG,
|
||||||
|
...ADDITIONAL_TAGS.split(',')
|
||||||
|
.map((t) => t.trim())
|
||||||
|
.filter(Boolean),
|
||||||
|
];
|
||||||
|
const releases = [];
|
||||||
|
|
||||||
|
for (const tag of allTags) {
|
||||||
|
const existingRelease = await getExistingRelease(tag);
|
||||||
|
const isReleaseTrackTag = isReleaseTrack(tag);
|
||||||
|
|
||||||
|
// If we have an existing track release, we want to
|
||||||
|
// delete the old release before pushing a new one.
|
||||||
|
if (isReleaseTrackTag && existingRelease) {
|
||||||
|
await deleteRelease(existingRelease.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const releaseResponse = await octokit.rest.repos.createRelease({
|
||||||
|
tag_name: tag,
|
||||||
|
name: tag,
|
||||||
|
body: BODY,
|
||||||
|
draft: false,
|
||||||
|
prerelease: IS_PRE_RELEASE === 'true',
|
||||||
|
make_latest: MAKE_LATEST === 'true' ? 'true' : 'false',
|
||||||
|
target_commitish: COMMIT,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
});
|
||||||
|
|
||||||
|
const release = releaseResponse.data;
|
||||||
|
releases.push(release);
|
||||||
|
|
||||||
|
console.log(`Successfully created release ${release.html_url}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeGithubOutput({
|
||||||
|
release_urls: releases.map((release) => release.html_url).join(', '),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// only run when executed directly, not when imported by tests
|
||||||
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||||
|
createGitHubRelease();
|
||||||
|
}
|
||||||
4
.github/scripts/determine-version-info.mjs
vendored
4
.github/scripts/determine-version-info.mjs
vendored
|
|
@ -74,7 +74,9 @@ export function determineTrack(packageVersion) {
|
||||||
|
|
||||||
writeGithubOutput(output);
|
writeGithubOutput(output);
|
||||||
console.log(
|
console.log(
|
||||||
`Determined track info: track=${track}, version=${packageVersion}, previous_version=${previousVersion}, new_stable_version=${newStable}, release_type=${releaseType}, rc_branch=${rc_branch}`,
|
`Determined track info: ${Object.entries(output)
|
||||||
|
.map(([key, val]) => `${key}=${val}`)
|
||||||
|
.join(', ')}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
||||||
47
.github/scripts/github-helpers.mjs
vendored
47
.github/scripts/github-helpers.mjs
vendored
|
|
@ -14,6 +14,10 @@ export const RELEASE_TRACKS = /** @type { const } */ ([
|
||||||
'v1',
|
'v1',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef { InstanceType<typeof import("@actions/github/lib/utils").GitHub> } GitHubInstance
|
||||||
|
* */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {typeof RELEASE_TRACKS[number]} ReleaseTrack
|
* @typedef {typeof RELEASE_TRACKS[number]} ReleaseTrack
|
||||||
* */
|
* */
|
||||||
|
|
@ -50,6 +54,15 @@ export function pickHighestReleaseTag(tags) {
|
||||||
return /** @type { ReleaseVersion } */ (versions[0]?.tag) ?? null;
|
return /** @type { ReleaseVersion } */ (versions[0]?.tag) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} track
|
||||||
|
*
|
||||||
|
* @returns { track is ReleaseTrack }
|
||||||
|
* */
|
||||||
|
export function isReleaseTrack(track) {
|
||||||
|
return RELEASE_TRACKS.includes(track);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {any} track
|
* @param {any} track
|
||||||
*
|
*
|
||||||
|
|
@ -337,3 +350,37 @@ export async function getPullRequestById(pullRequestId) {
|
||||||
|
|
||||||
return pullRequest.data;
|
return pullRequest.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} tag
|
||||||
|
*/
|
||||||
|
export async function getExistingRelease(tag) {
|
||||||
|
const { octokit, owner, repo } = initGithub();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const releaseRequest = await octokit.rest.repos.getReleaseByTag({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
tag,
|
||||||
|
});
|
||||||
|
|
||||||
|
return releaseRequest.data;
|
||||||
|
} catch (ex) {
|
||||||
|
if (ex?.status === 404) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} releaseId
|
||||||
|
*/
|
||||||
|
export async function deleteRelease(releaseId) {
|
||||||
|
const { octokit, owner, repo } = initGithub();
|
||||||
|
await octokit.rest.repos.deleteRelease({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
release_id: releaseId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
2
.github/scripts/jsconfig.json
vendored
2
.github/scripts/jsconfig.json
vendored
|
|
@ -3,7 +3,7 @@
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"target": "esnext",
|
"target": "esnext",
|
||||||
"checkJs": true,
|
"checkJs": true,
|
||||||
"moduleResolution": "node"
|
"moduleResolution": "bundler"
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
.github/scripts/package.json
vendored
3
.github/scripts/package.json
vendored
|
|
@ -5,6 +5,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/github": "9.0.0",
|
"@actions/github": "9.0.0",
|
||||||
|
"@octokit/core": "7.0.6",
|
||||||
"conventional-changelog": "7.2.0",
|
"conventional-changelog": "7.2.0",
|
||||||
"debug": "4.4.3",
|
"debug": "4.4.3",
|
||||||
"glob": "13.0.6",
|
"glob": "13.0.6",
|
||||||
|
|
@ -12,6 +13,6 @@
|
||||||
"tempfile": "6.0.1"
|
"tempfile": "6.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"conventional-changelog-angular": "^8.3.0"
|
"conventional-changelog-angular": "8.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
.github/scripts/pnpm-lock.yaml
vendored
5
.github/scripts/pnpm-lock.yaml
vendored
|
|
@ -11,6 +11,9 @@ importers:
|
||||||
'@actions/github':
|
'@actions/github':
|
||||||
specifier: 9.0.0
|
specifier: 9.0.0
|
||||||
version: 9.0.0
|
version: 9.0.0
|
||||||
|
'@octokit/core':
|
||||||
|
specifier: 7.0.6
|
||||||
|
version: 7.0.6
|
||||||
conventional-changelog:
|
conventional-changelog:
|
||||||
specifier: 7.2.0
|
specifier: 7.2.0
|
||||||
version: 7.2.0(conventional-commits-filter@5.0.0)
|
version: 7.2.0(conventional-commits-filter@5.0.0)
|
||||||
|
|
@ -28,7 +31,7 @@ importers:
|
||||||
version: 6.0.1
|
version: 6.0.1
|
||||||
devDependencies:
|
devDependencies:
|
||||||
conventional-changelog-angular:
|
conventional-changelog-angular:
|
||||||
specifier: ^8.3.0
|
specifier: 8.3.0
|
||||||
version: 8.3.0
|
version: 8.3.0
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
|
||||||
45
.github/scripts/promote-github-release.mjs
vendored
Normal file
45
.github/scripts/promote-github-release.mjs
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import {
|
||||||
|
ensureEnvVar,
|
||||||
|
getExistingRelease,
|
||||||
|
initGithub,
|
||||||
|
writeGithubOutput,
|
||||||
|
} from './github-helpers.mjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Promotes a GitHub release to latest
|
||||||
|
*
|
||||||
|
* Required env variables:
|
||||||
|
* - RELEASE_TAG - Release tag on git e.g. n8n@2.13.0
|
||||||
|
*
|
||||||
|
* GitHub variables
|
||||||
|
* - GITHUB_TOKEN - Used to authenticate to octokit - Can be overwritten for privileged access
|
||||||
|
* - GITHUB_REPOSITORY - Used to determine target repository
|
||||||
|
* */
|
||||||
|
async function promoteGitHubRelease() {
|
||||||
|
const RELEASE_TAG = ensureEnvVar('RELEASE_TAG');
|
||||||
|
const { octokit, owner, repo } = initGithub();
|
||||||
|
|
||||||
|
const existingRelease = await getExistingRelease(RELEASE_TAG);
|
||||||
|
if (!existingRelease) {
|
||||||
|
console.warn("Couldn't find release by tag. Exiting...");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const releaseResponse = await octokit.rest.repos.updateRelease({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
release_id: existingRelease.id,
|
||||||
|
make_latest: 'true',
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Successfully updated release ${releaseResponse.data.html_url}`);
|
||||||
|
|
||||||
|
writeGithubOutput({
|
||||||
|
release_url: releaseResponse.data.html_url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// only run when executed directly, not when imported by tests
|
||||||
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||||
|
promoteGitHubRelease();
|
||||||
|
}
|
||||||
78
.github/workflows/release-create-github-releases.yml
vendored
Normal file
78
.github/workflows/release-create-github-releases.yml
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
name: 'Release: Create GitHub Releases'
|
||||||
|
run-name: 'Creating GitHub Releases for ${{ inputs.version-tag }} (${{ inputs.track }})'
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
track:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
version-tag:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
body:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
commit:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
track:
|
||||||
|
description: 'Release Track'
|
||||||
|
required: true
|
||||||
|
type: choice
|
||||||
|
options: [stable, beta, v1]
|
||||||
|
version-tag:
|
||||||
|
description: 'Version tag (e.g. n8n@2.7.0).'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
body:
|
||||||
|
description: 'Release notes body.'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
commit:
|
||||||
|
description: 'Commitish the release points to (e.g. branch name or SHA).'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create-github-releases:
|
||||||
|
name: Create GitHub releases
|
||||||
|
runs-on: ubuntu-slim
|
||||||
|
environment: release
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Generate GitHub App Token
|
||||||
|
id: generate_token
|
||||||
|
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||||
|
with:
|
||||||
|
app-id: ${{ secrets.N8N_ASSISTANT_APP_ID }}
|
||||||
|
private-key: ${{ secrets.N8N_ASSISTANT_PRIVATE_KEY }}
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
with:
|
||||||
|
token: ${{ steps.generate_token.outputs.token }}
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Setup NodeJS
|
||||||
|
uses: ./.github/actions/setup-nodejs
|
||||||
|
with:
|
||||||
|
build-command: ''
|
||||||
|
install-command: pnpm install --frozen-lockfile --dir ./.github/scripts --ignore-workspace
|
||||||
|
|
||||||
|
- name: Create GitHub releases
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||||
|
RELEASE_TAG: ${{ inputs.version-tag }}
|
||||||
|
BODY: ${{ inputs.body }}
|
||||||
|
IS_PRE_RELEASE: ${{ inputs.track == 'beta' }}
|
||||||
|
MAKE_LATEST: ${{ inputs.track == 'stable' }}
|
||||||
|
COMMIT: ${{ inputs.commit }}
|
||||||
|
ADDITIONAL_TAGS: ${{ inputs.track }}
|
||||||
|
run: node ./.github/scripts/create-github-release.mjs
|
||||||
50
.github/workflows/release-promote-github-release.yml
vendored
Normal file
50
.github/workflows/release-promote-github-release.yml
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
name: 'Release: Promote GitHub Releases'
|
||||||
|
run-name: 'Promoting GitHub Release ${{ inputs.version-tag }} to latest'
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
version-tag:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version-tag:
|
||||||
|
description: 'Version tag (e.g. n8n@2.7.0).'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
promote-github-releases:
|
||||||
|
name: Promote GitHub release to latest
|
||||||
|
runs-on: ubuntu-slim
|
||||||
|
environment: release
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Generate GitHub App Token
|
||||||
|
id: generate_token
|
||||||
|
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||||
|
with:
|
||||||
|
app-id: ${{ secrets.N8N_ASSISTANT_APP_ID }}
|
||||||
|
private-key: ${{ secrets.N8N_ASSISTANT_PRIVATE_KEY }}
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
with:
|
||||||
|
token: ${{ steps.generate_token.outputs.token }}
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Setup NodeJS
|
||||||
|
uses: ./.github/actions/setup-nodejs
|
||||||
|
with:
|
||||||
|
build-command: ''
|
||||||
|
install-command: pnpm install --frozen-lockfile --dir ./.github/scripts --ignore-workspace
|
||||||
|
|
||||||
|
- name: Promote GitHub releases
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||||
|
RELEASE_TAG: ${{ inputs.version-tag }}
|
||||||
|
run: node ./.github/scripts/promote-github-release.mjs
|
||||||
|
|
@ -49,6 +49,16 @@ jobs:
|
||||||
version: ${{ inputs.new_stable_version }}
|
version: ${{ inputs.new_stable_version }}
|
||||||
release-channel: stable
|
release-channel: stable
|
||||||
|
|
||||||
|
promote-previous-minor-github-release-to-latest:
|
||||||
|
name: Promote previous minor Github Release to latest
|
||||||
|
if: |
|
||||||
|
inputs.release_type != 'rc' &&
|
||||||
|
inputs.bump == 'minor'
|
||||||
|
uses: ./.github/workflows/release-promote-github-release.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
version-tag: 'n8n@${{ inputs.new_stable_version }}'
|
||||||
|
|
||||||
ensure-release-candidate-branches:
|
ensure-release-candidate-branches:
|
||||||
name: 'Ensure release candidate branches'
|
name: 'Ensure release candidate branches'
|
||||||
if: |
|
if: |
|
||||||
|
|
|
||||||
33
.github/workflows/release-publish.yml
vendored
33
.github/workflows/release-publish.yml
vendored
|
|
@ -97,33 +97,16 @@ jobs:
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
create-github-release:
|
create-github-release:
|
||||||
name: Create a GitHub Release
|
name: Create GitHub Release
|
||||||
needs: [determine-version-info, publish-to-npm, publish-to-docker-hub]
|
needs: [determine-version-info, publish-to-npm, publish-to-docker-hub]
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event.pull_request.merged == true
|
if: github.event.pull_request.merged == true
|
||||||
timeout-minutes: 5
|
uses: ./.github/workflows/release-create-github-releases.yml
|
||||||
|
with:
|
||||||
permissions:
|
track: ${{ needs.determine-version-info.outputs.track }}
|
||||||
contents: write
|
version-tag: 'n8n@${{ needs.determine-version-info.outputs.version }}'
|
||||||
id-token: write
|
body: ${{ github.event.pull_request.body }}
|
||||||
|
commit: ${{ github.event.pull_request.base.ref }}
|
||||||
steps:
|
secrets: inherit
|
||||||
- name: Generate GitHub App Token
|
|
||||||
id: generate_token
|
|
||||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
|
||||||
with:
|
|
||||||
app-id: ${{ secrets.N8N_ASSISTANT_APP_ID }}
|
|
||||||
private-key: ${{ secrets.N8N_ASSISTANT_PRIVATE_KEY }}
|
|
||||||
|
|
||||||
- name: Create a Release on GitHub
|
|
||||||
uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1.20.0
|
|
||||||
with:
|
|
||||||
token: ${{ steps.generate_token.outputs.token }}
|
|
||||||
commit: ${{github.event.pull_request.base.ref}}
|
|
||||||
tag: 'n8n@${{ needs.determine-version-info.outputs.version }}'
|
|
||||||
prerelease: ${{ needs.determine-version-info.outputs.track == 'beta' }}
|
|
||||||
makeLatest: ${{ needs.determine-version-info.outputs.track == 'stable' }}
|
|
||||||
body: ${{github.event.pull_request.body}}
|
|
||||||
|
|
||||||
move-track-tag:
|
move-track-tag:
|
||||||
name: Move track tag
|
name: Move track tag
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user