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);
|
||||
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;
|
||||
|
|
|
|||
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',
|
||||
]);
|
||||
|
||||
/**
|
||||
* @typedef { InstanceType<typeof import("@actions/github/lib/utils").GitHub> } GitHubInstance
|
||||
* */
|
||||
|
||||
/**
|
||||
* @typedef {typeof RELEASE_TRACKS[number]} ReleaseTrack
|
||||
* */
|
||||
|
|
@ -50,6 +54,15 @@ export function pickHighestReleaseTag(tags) {
|
|||
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
|
||||
*
|
||||
|
|
@ -337,3 +350,37 @@ export async function getPullRequestById(pullRequestId) {
|
|||
|
||||
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",
|
||||
"target": "esnext",
|
||||
"checkJs": true,
|
||||
"moduleResolution": "node"
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
|
|
|||
3
.github/scripts/package.json
vendored
3
.github/scripts/package.json
vendored
|
|
@ -5,6 +5,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@actions/github": "9.0.0",
|
||||
"@octokit/core": "7.0.6",
|
||||
"conventional-changelog": "7.2.0",
|
||||
"debug": "4.4.3",
|
||||
"glob": "13.0.6",
|
||||
|
|
@ -12,6 +13,6 @@
|
|||
"tempfile": "6.0.1"
|
||||
},
|
||||
"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':
|
||||
specifier: 9.0.0
|
||||
version: 9.0.0
|
||||
'@octokit/core':
|
||||
specifier: 7.0.6
|
||||
version: 7.0.6
|
||||
conventional-changelog:
|
||||
specifier: 7.2.0
|
||||
version: 7.2.0(conventional-commits-filter@5.0.0)
|
||||
|
|
@ -28,7 +31,7 @@ importers:
|
|||
version: 6.0.1
|
||||
devDependencies:
|
||||
conventional-changelog-angular:
|
||||
specifier: ^8.3.0
|
||||
specifier: 8.3.0
|
||||
version: 8.3.0
|
||||
|
||||
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 }}
|
||||
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:
|
||||
name: 'Ensure release candidate branches'
|
||||
if: |
|
||||
|
|
|
|||
33
.github/workflows/release-publish.yml
vendored
33
.github/workflows/release-publish.yml
vendored
|
|
@ -97,33 +97,16 @@ jobs:
|
|||
secrets: inherit
|
||||
|
||||
create-github-release:
|
||||
name: Create a GitHub Release
|
||||
name: Create GitHub Release
|
||||
needs: [determine-version-info, publish-to-npm, publish-to-docker-hub]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.merged == true
|
||||
timeout-minutes: 5
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
|
||||
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: 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}}
|
||||
uses: ./.github/workflows/release-create-github-releases.yml
|
||||
with:
|
||||
track: ${{ needs.determine-version-info.outputs.track }}
|
||||
version-tag: 'n8n@${{ needs.determine-version-info.outputs.version }}'
|
||||
body: ${{ github.event.pull_request.body }}
|
||||
commit: ${{ github.event.pull_request.base.ref }}
|
||||
secrets: inherit
|
||||
|
||||
move-track-tag:
|
||||
name: Move track tag
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user