Merge branch '044-proper-release-process' into 'master'

Resolve "Proper release process"

Closes #44

See merge request dungeonslayers/ds4!39
This commit is contained in:
Johannes Loher 2021-01-09 19:40:25 +01:00
commit 41e5ca25a3
4 changed files with 62 additions and 107 deletions

View file

@ -5,6 +5,7 @@ stages:
- test - test
- build - build
- deploy - deploy
- release
cache: &global_cache cache: &global_cache
key: key:
@ -66,3 +67,46 @@ deploy:
only: only:
- master - master
resource_group: production resource_group: production
.release-template: &release-template
stage: release
before_script:
- apt update
- apt install --yes jq
- REPOSITORY_URL=$(echo "${CI_REPOSITORY_URL}" | sed -e "s|gitlab-ci-token:.*@|${RELEASE_TOKEN}:${RELEASE_TOKEN_SECRET}@|g")
- git remote set-url origin $REPOSITORY_URL
- git config user.name $GITLAB_USER_LOGIN
- git config user.email $GITLAB_USER_EMAIL
- git branch -D ci-processing || true
- git checkout -b ci-processing
cache:
<<: *global_cache
script: |
npm run updateManifest -- --update=${RELEASE_TYPE}
RELEASE_VERSION=$(jq -r '.version' < package.json)
git add package.json package-lock.json src/system.json
git --no-pager diff
git commit -m "release version ${RELEASE_VERSION}"
git tag -f latest
git tag -f ${RELEASE_VERSION}
git push origin ci-processing:${CI_BUILD_REF_NAME}
git push origin latest -f
git push origin ${RELEASE_VERSION}
only:
- master
when: manual
release-patch:
variables:
RELEASE_TYPE: patch
<<: *release-template
release-minor:
variables:
RELEASE_TYPE: minor
<<: *release-template
release-major:
variables:
RELEASE_TYPE: major
<<: *release-template

View file

@ -2,14 +2,11 @@ const gulp = require("gulp");
const fs = require("fs-extra"); const fs = require("fs-extra");
const path = require("path"); const path = require("path");
const chalk = require("chalk"); const chalk = require("chalk");
const archiver = require("archiver");
const stringify = require("json-stringify-pretty-compact"); const stringify = require("json-stringify-pretty-compact");
const typescript = require("typescript"); const typescript = require("typescript");
const ts = require("gulp-typescript"); const ts = require("gulp-typescript");
const less = require("gulp-less");
const sass = require("gulp-sass"); const sass = require("gulp-sass");
const git = require("gulp-git");
const argv = require("yargs").argv; const argv = require("yargs").argv;
@ -127,13 +124,6 @@ function buildTS() {
return gulp.src("src/**/*.ts").pipe(tsConfig()).pipe(gulp.dest("dist")); return gulp.src("src/**/*.ts").pipe(tsConfig()).pipe(gulp.dest("dist"));
} }
/**
* Build Less
*/
function buildLess() {
return gulp.src("src/*.less").pipe(less()).pipe(gulp.dest("dist"));
}
/** /**
* Build SASS * Build SASS
*/ */
@ -163,7 +153,6 @@ async function copyFiles() {
*/ */
function buildWatch() { function buildWatch() {
gulp.watch("src/**/*.ts", { ignoreInitial: false }, buildTS); gulp.watch("src/**/*.ts", { ignoreInitial: false }, buildTS);
gulp.watch("src/**/*.less", { ignoreInitial: false }, buildLess);
gulp.watch("src/**/*.scss", { ignoreInitial: false }, buildSASS); gulp.watch("src/**/*.scss", { ignoreInitial: false }, buildSASS);
gulp.watch(["src/fonts", "src/lang", "src/templates", "src/*.json"], { ignoreInitial: false }, copyFiles); gulp.watch(["src/fonts", "src/lang", "src/templates", "src/*.json"], { ignoreInitial: false }, copyFiles);
} }
@ -194,8 +183,8 @@ async function clean() {
); );
} }
// If the project uses Less or SASS // If the project uses SASS
if (fs.existsSync(path.join("src", `${name}.less`)) || fs.existsSync(path.join("src", `${name}.scss`))) { if (fs.existsSync(path.join("src", `${name}.scss`))) {
files.push("fonts", `${name}.css`); files.push("fonts", `${name}.css`);
} }
@ -268,69 +257,15 @@ async function linkUserData() {
/* PACKAGE */ /* PACKAGE */
/*********************/ /*********************/
/**
* Package build
*/
async function packageBuild() {
const manifest = getManifest();
return new Promise((resolve, reject) => {
try {
// Remove the package dir without doing anything else
if (argv.clean || argv.c) {
console.log(chalk.yellow("Removing all packaged files"));
fs.removeSync("package");
return;
}
// Ensure there is a directory to hold all the packaged versions
fs.ensureDirSync("package");
// Initialize the zip file
const zipName = `${manifest.file.name}-v${manifest.file.version}.zip`;
const zipFile = fs.createWriteStream(path.join("package", zipName));
const zip = archiver("zip", { zlib: { level: 9 } });
zipFile.on("close", () => {
console.log(chalk.green(zip.pointer() + " total bytes"));
console.log(chalk.green(`Zip file ${zipName} has been written`));
return resolve();
});
zip.on("error", (err) => {
throw err;
});
zip.pipe(zipFile);
// Add the directory with the final code
zip.directory("dist/", manifest.file.name);
zip.finalize();
} catch (err) {
return reject(err);
}
});
}
/*********************/
/* PACKAGE */
/*********************/
/** /**
* Update version and URLs in the manifest JSON * Update version and URLs in the manifest JSON
*/ */
function updateManifest(cb) { function updateManifest(cb) {
const packageJson = fs.readJSONSync("package.json"); const packageJson = fs.readJSONSync("package.json");
const config = getConfig(), const packageLockJson = fs.readJSONSync("package-lock.json");
manifest = getManifest(), const manifest = getManifest();
rawURL = config.rawURL,
repoURL = config.repository,
manifestRoot = manifest.root;
if (!config) cb(Error(chalk.red("foundryconfig.json not found")));
if (!manifest) cb(Error(chalk.red("Manifest JSON not found"))); if (!manifest) cb(Error(chalk.red("Manifest JSON not found")));
if (!rawURL || !repoURL) cb(Error(chalk.red("Repository URLs not configured in foundryconfig.json")));
try { try {
const version = argv.update || argv.u; const version = argv.update || argv.u;
@ -372,22 +307,22 @@ function updateManifest(cb) {
console.log(`Updating version number to '${targetVersion}'`); console.log(`Updating version number to '${targetVersion}'`);
packageJson.version = targetVersion; packageJson.version = targetVersion;
packageLockJson.version = targetVersion;
manifest.file.version = targetVersion; manifest.file.version = targetVersion;
/* Update URLs */ /* Update URL */
const result = `https://git.f3l.de/dungeonslayers/ds4/-/jobs/artifacts/${targetVersion}/download?job=build`;
const result = `${rawURL}/v${manifest.file.version}/package/${manifest.file.name}-v${manifest.file.version}.zip`;
manifest.file.url = repoURL;
manifest.file.manifest = `${rawURL}/master/${manifestRoot}/${manifest.name}`;
manifest.file.download = result; manifest.file.download = result;
const prettyProjectJson = stringify(manifest.file, { const prettyProjectJson =
maxLength: 35, stringify(manifest.file, {
indent: "\t", maxLength: 40,
}); indent: 4,
}) + "\n";
fs.writeJSONSync("package.json", packageJson, { spaces: "\t" }); fs.writeJSONSync("package.json", packageJson, { spaces: 4 });
fs.writeJSONSync("package-lock.json", packageLockJson, { spaces: 4 });
fs.writeFileSync(path.join(manifest.root, manifest.name), prettyProjectJson, "utf8"); fs.writeFileSync(path.join(manifest.root, manifest.name), prettyProjectJson, "utf8");
return cb(); return cb();
@ -396,34 +331,10 @@ function updateManifest(cb) {
} }
} }
function gitAdd() { const execBuild = gulp.parallel(buildTS, buildSASS, copyFiles);
return gulp.src("package").pipe(git.add({ args: "--no-all" }));
}
function gitCommit() {
return gulp.src("./*").pipe(
git.commit(`v${getManifest().file.version}`, {
args: "-a",
disableAppendPaths: true,
}),
);
}
function gitTag() {
const manifest = getManifest();
return git.tag(`v${manifest.file.version}`, `Updated to ${manifest.file.version}`, (err) => {
if (err) throw err;
});
}
const execGit = gulp.series(gitAdd, gitCommit, gitTag);
const execBuild = gulp.parallel(buildTS, buildLess, buildSASS, copyFiles);
exports.build = gulp.series(clean, execBuild); exports.build = gulp.series(clean, execBuild);
exports.watch = buildWatch; exports.watch = buildWatch;
exports.clean = clean; exports.clean = clean;
exports.link = linkUserData; exports.link = linkUserData;
exports.package = packageBuild; exports.updateManifest = updateManifest;
exports.update = updateManifest;
exports.publish = gulp.series(clean, updateManifest, execBuild, packageBuild, execGit);

View file

@ -27,12 +27,12 @@
} }
], ],
"scripts": { "scripts": {
"package": "gulp package",
"build": "gulp build", "build": "gulp build",
"build:watch": "gulp watch", "build:watch": "gulp watch",
"link": "gulp link", "link": "gulp link",
"clean": "gulp clean && gulp link --clean", "clean": "gulp clean && gulp link --clean",
"update": "npm install --save-dev git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#f3l-fixes", "update": "npm install --save-dev git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#f3l-fixes",
"updateManifest": "gulp updateManifest",
"lint": "eslint 'src/**/*.ts' --cache", "lint": "eslint 'src/**/*.ts' --cache",
"lint:fix": "eslint 'src/**/*.ts' --cache --fix", "lint:fix": "eslint 'src/**/*.ts' --cache --fix",
"test": "ts-node ./node_modules/jasmine/bin/jasmine", "test": "ts-node ./node_modules/jasmine/bin/jasmine",

View file

@ -22,7 +22,7 @@
"gridUnits": "m", "gridUnits": "m",
"primaryTokenAttribute": "combatValues.hitPoints", "primaryTokenAttribute": "combatValues.hitPoints",
"url": "https://git.f3l.de/dungeonslayers/ds4", "url": "https://git.f3l.de/dungeonslayers/ds4",
"manifest": "https://git.f3l.de/dungeonslayers/ds4/-/raw/master/src/system.json?inline=false", "manifest": "https://git.f3l.de/dungeonslayers/ds4/-/raw/latest/src/system.json?inline=false",
"download": "https://git.f3l.de/dungeonslayers/ds4/-/jobs/artifacts/0.1.0/download?job=build", "download": "https://git.f3l.de/dungeonslayers/ds4/-/jobs/artifacts/0.1.0/download?job=build",
"license": "MIT" "license": "MIT"
} }