| | #!/usr/bin/env node |
| |
|
| | import { appendFileSync } from 'node:fs'; |
| |
|
| | class BuildContext { |
| | constructor() { |
| | this.githubOutput = process.env.GITHUB_OUTPUT || null; |
| | } |
| |
|
| | determine({ event, pr, branch, version, releaseType, pushEnabled }) { |
| | let context = { |
| | version: '', |
| | release_type: '', |
| | platforms: ['linux/amd64', 'linux/arm64'], |
| | push_to_ghcr: true, |
| | push_to_docker: false, |
| | }; |
| |
|
| | if (version && releaseType) { |
| | context.version = version; |
| | context.release_type = releaseType; |
| | context.push_to_docker = true; |
| | } else { |
| | switch (event) { |
| | case 'schedule': |
| | context.version = 'nightly'; |
| | context.release_type = 'nightly'; |
| | context.push_to_docker = true; |
| | break; |
| |
|
| | case 'pull_request': |
| | context.version = `pr-${pr}`; |
| | context.release_type = 'dev'; |
| | context.platforms = ['linux/amd64']; |
| | break; |
| |
|
| | case 'workflow_dispatch': |
| | context.version = `branch-${this.sanitizeBranch(branch)}`; |
| | context.release_type = 'branch'; |
| | context.platforms = ['linux/amd64']; |
| | break; |
| |
|
| | case 'push': |
| | if (branch === 'master') { |
| | context.version = 'dev'; |
| | context.release_type = 'dev'; |
| | context.push_to_docker = true; |
| | } else { |
| | context.version = `branch-${this.sanitizeBranch(branch)}`; |
| | context.release_type = 'branch'; |
| | context.platforms = ['linux/amd64']; |
| | } |
| | break; |
| |
|
| | case 'workflow_call': |
| | case 'release': |
| | if (!version) throw new Error('Version required for release'); |
| | context.version = version; |
| | context.release_type = releaseType || 'stable'; |
| | context.push_to_docker = true; |
| | break; |
| |
|
| | default: |
| | throw new Error(`Unknown event: ${event}`); |
| | } |
| | } |
| |
|
| | |
| | if (pushEnabled !== undefined) { |
| | context.push_enabled = pushEnabled; |
| | } else { |
| | context.push_enabled = context.push_to_ghcr; |
| | } |
| |
|
| | return context; |
| | } |
| |
|
| | sanitizeBranch(branch) { |
| | if (!branch) return 'unknown'; |
| | return branch |
| | .toLowerCase() |
| | .replace(/[^a-z0-9._-]/g, '-') |
| | .replace(/^[.-]/, '') |
| | .replace(/[.-]$/, '') |
| | .substring(0, 128); |
| | } |
| |
|
| | buildMatrix(platforms) { |
| | const runners = { |
| | 'linux/amd64': 'blacksmith-4vcpu-ubuntu-2204', |
| | 'linux/arm64': 'blacksmith-4vcpu-ubuntu-2204-arm', |
| | }; |
| |
|
| | const matrix = { |
| | platform: [], |
| | include: [], |
| | }; |
| |
|
| | for (const platform of platforms) { |
| | const shortName = platform.split('/').pop(); |
| | matrix.platform.push(shortName); |
| | matrix.include.push({ |
| | platform: shortName, |
| | runner: runners[platform], |
| | docker_platform: platform, |
| | }); |
| | } |
| |
|
| | return matrix; |
| | } |
| |
|
| | output(context, matrix = null) { |
| | const buildMatrix = matrix || this.buildMatrix(context.platforms); |
| |
|
| | if (this.githubOutput) { |
| | const outputs = [ |
| | `version=${context.version}`, |
| | `release_type=${context.release_type}`, |
| | `platforms=${JSON.stringify(context.platforms)}`, |
| | `push_to_ghcr=${context.push_to_ghcr}`, |
| | `push_to_docker=${context.push_to_docker}`, |
| | `push_enabled=${context.push_enabled}`, |
| | `build_matrix=${JSON.stringify(buildMatrix)}`, |
| | ]; |
| | appendFileSync(this.githubOutput, outputs.join('\n') + '\n'); |
| | } else { |
| | console.log(JSON.stringify({ ...context, build_matrix: buildMatrix }, null, 2)); |
| | } |
| | } |
| | } |
| |
|
| | |
| | if (import.meta.url === `file://${process.argv[1]}`) { |
| | const args = process.argv.slice(2); |
| | const getArg = (name) => { |
| | const index = args.indexOf(`--${name}`); |
| | if (index === -1 || !args[index + 1]) return undefined; |
| | const value = args[index + 1]; |
| | |
| | return value === '' || value === 'null' ? undefined : value; |
| | }; |
| |
|
| | try { |
| | const context = new BuildContext(); |
| | const pushEnabledArg = getArg('push-enabled'); |
| | const result = context.determine({ |
| | event: getArg('event') || process.env.GITHUB_EVENT_NAME, |
| | pr: getArg('pr') || process.env.GITHUB_PR_NUMBER, |
| | branch: getArg('branch') || process.env.GITHUB_REF_NAME, |
| | version: getArg('version'), |
| | releaseType: getArg('release-type'), |
| | pushEnabled: |
| | pushEnabledArg === 'true' ? true : pushEnabledArg === 'false' ? false : undefined, |
| | }); |
| |
|
| | const matrix = context.buildMatrix(result.platforms); |
| |
|
| | |
| | if (context.githubOutput) { |
| | console.log('=== Build Context ==='); |
| | console.log(`version: ${result.version}`); |
| | console.log(`release_type: ${result.release_type}`); |
| | console.log(`platforms: ${JSON.stringify(result.platforms, null, 2)}`); |
| | console.log(`push_to_ghcr: ${result.push_to_ghcr}`); |
| | console.log(`push_to_docker: ${result.push_to_docker}`); |
| | console.log(`push_enabled: ${result.push_enabled}`); |
| | console.log('build_matrix:', JSON.stringify(matrix, null, 2)); |
| | } |
| |
|
| | context.output(result, matrix); |
| | } catch (error) { |
| | console.error(`Error: ${error.message}`); |
| | process.exit(1); |
| | } |
| | } |
| |
|
| | export default BuildContext; |
| |
|