You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-23 22:36:32 +02:00
167 lines
5.3 KiB
TypeScript
167 lines
5.3 KiB
TypeScript
import { rootDir } from './tool-utils';
|
|
import * as moment from 'moment';
|
|
import { execCommand } from '@joplin/utils';
|
|
|
|
interface Argv {
|
|
dryRun?: boolean;
|
|
pushImages?: boolean;
|
|
repository?: string;
|
|
tagName?: string;
|
|
platform?: string;
|
|
source?: string;
|
|
addLatestTag?: boolean;
|
|
dockerFile?: string;
|
|
}
|
|
|
|
function parseArgv(): Argv {
|
|
return require('yargs')
|
|
.scriptName('yarn buildServerDocker')
|
|
.usage('$0 --repository OWNER/IMAGE [args]')
|
|
.option('dockerFile', {
|
|
describe: 'Dockerfile - either Dockerfile.server or Dockerfile.transcribe',
|
|
demandOption: true,
|
|
type: 'string',
|
|
})
|
|
.option('repository', {
|
|
describe: 'Target image repository. Usually in format `OWNER/NAME`',
|
|
demandOption: true,
|
|
type: 'string',
|
|
})
|
|
.option('tagName', {
|
|
describe: 'Base image tag. Usually should be in format `server-v1.2.3` or `server-v1.2.3-beta`. The latest `server-v*` git tag will be used by default.',
|
|
type: 'string',
|
|
})
|
|
.option('addLatestTag', {
|
|
describe: 'Add `latest` tag even for pre-release images.',
|
|
type: 'boolean',
|
|
default: false,
|
|
})
|
|
.option('platform', {
|
|
describe: 'Comma separated list of target image platforms. E.g. `linux/amd64` or `linux/amd64,linux/arm64`',
|
|
type: 'string',
|
|
default: 'linux/amd64',
|
|
})
|
|
.option('source', {
|
|
describe: 'Source Git repository for the images.',
|
|
type: 'string',
|
|
default: 'https://github.com/laurent22/joplin.git',
|
|
})
|
|
.option('pushImages', {
|
|
describe: 'Publish images to target repository.',
|
|
type: 'boolean',
|
|
default: false,
|
|
})
|
|
.option('dryRun', {
|
|
describe: 'Do not call docker, just show command instead.',
|
|
type: 'boolean',
|
|
default: false,
|
|
})
|
|
.help()
|
|
.argv as Argv;
|
|
}
|
|
|
|
export function getVersionFromTag(tagName: string, isPreRelease: boolean): string {
|
|
const s = tagName.split('-');
|
|
const mainVersion = s[1].replace(/^(v)/, '');
|
|
const metaComponents = s.slice(2).filter(item => item !== 'beta');
|
|
|
|
// Append `git describe` components for pre release images. Mostly for case without `tagName` arg
|
|
const suffix = isPreRelease ? `-beta${metaComponents.length > 0 ? `.${metaComponents.join('.')}` : ''}` : '';
|
|
return mainVersion + suffix;
|
|
}
|
|
|
|
export function getIsPreRelease(_tagName: string): boolean {
|
|
// For now we only create pre-releases from CI. It's after, once the release
|
|
// has been proven stable, that it is tagged as "latest".
|
|
return false;
|
|
// return tagName.indexOf('-beta') > 0;
|
|
}
|
|
|
|
async function main() {
|
|
const argv = parseArgv();
|
|
if (!argv.tagName) console.info('No `--tag-name` was specified. A latest git tag will be used instead.');
|
|
|
|
console.info('Raw arguments:', argv);
|
|
|
|
const dryRun = argv.dryRun;
|
|
const addLatestTag = argv.addLatestTag;
|
|
const dockerFile = argv.dockerFile;
|
|
const pushImages = argv.pushImages;
|
|
const repository = argv.repository;
|
|
const tagName = argv.tagName || `server-${await execCommand('git describe --tags --match v*', { showStdout: false })}`;
|
|
const platform = argv.platform;
|
|
const source = argv.source;
|
|
const architecture = argv.platform.split('/')[1];
|
|
|
|
const isPreRelease = getIsPreRelease(tagName);
|
|
const imageVersion = getVersionFromTag(tagName, isPreRelease);
|
|
const buildDate = moment(new Date().getTime()).format('YYYY-MM-DDTHH:mm:ssZ');
|
|
let revision = '';
|
|
try {
|
|
revision = await execCommand('git rev-parse --short HEAD', { showStdout: false });
|
|
} catch (error) {
|
|
console.info('Could not get git commit: metadata revision field will be empty');
|
|
}
|
|
|
|
const buildArgs = [];
|
|
buildArgs.push(`BUILD_DATE="${buildDate}"`);
|
|
buildArgs.push(`REVISION="${revision}"`);
|
|
buildArgs.push(`VERSION="${imageVersion}"`);
|
|
buildArgs.push(`SOURCE="${source}"`);
|
|
|
|
const dockerTags: string[] = [];
|
|
const versionParts = imageVersion.split('.');
|
|
const patchVersionPart = versionParts[2].split('-')[0];
|
|
dockerTags.push(isPreRelease ? 'latest-beta' : 'latest');
|
|
dockerTags.push(versionParts[0] + (isPreRelease ? '-beta' : ''));
|
|
dockerTags.push(`${versionParts[0]}.${versionParts[1]}${isPreRelease ? '-beta' : ''}`);
|
|
dockerTags.push(`${versionParts[0]}.${versionParts[1]}.${patchVersionPart}${isPreRelease ? '-beta' : ''}`);
|
|
if (dockerTags.indexOf(imageVersion) < 0) {
|
|
dockerTags.push(imageVersion);
|
|
}
|
|
if (addLatestTag && dockerTags.indexOf('latest') < 0) {
|
|
dockerTags.push('latest');
|
|
}
|
|
|
|
|
|
process.chdir(rootDir);
|
|
console.info(`Running from: ${process.cwd()}`);
|
|
|
|
console.info('dockerFile:', dockerFile);
|
|
console.info('repository:', repository);
|
|
console.info('tagName:', tagName);
|
|
console.info('platform:', platform);
|
|
console.info('pushImages:', pushImages);
|
|
console.info('imageVersion:', imageVersion);
|
|
console.info('isPreRelease:', isPreRelease);
|
|
console.info('Docker tags:', dockerTags.join(', '));
|
|
|
|
const cliArgs = ['--progress=plain'];
|
|
cliArgs.push(`--platform ${platform}`);
|
|
cliArgs.push(...dockerTags.map(tag => `--tag "${repository}:${architecture}-${tag}"`));
|
|
cliArgs.push(...buildArgs.map(arg => `--build-arg ${arg}`));
|
|
if (pushImages) {
|
|
cliArgs.push('--push');
|
|
}
|
|
cliArgs.push(`--file ${dockerFile}`);
|
|
cliArgs.push('.');
|
|
|
|
const dockerCommand = `docker buildx build ${cliArgs.join(' ')}`;
|
|
|
|
console.info('exec:', dockerCommand);
|
|
if (dryRun) {
|
|
return;
|
|
}
|
|
|
|
await execCommand(dockerCommand);
|
|
}
|
|
|
|
if (require.main === module) {
|
|
// eslint-disable-next-line promise/prefer-await-to-then
|
|
main().catch((error) => {
|
|
console.error('Fatal error');
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|
|
}
|