From 74be1d4e13f2a630c65cf951b3f06f493019b2db Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Wed, 6 Jan 2021 00:59:22 +0100 Subject: [PATCH 1/6] put release artifacts in ds4 directory --- .gitlab-ci.yml | 5 +++-- src/system.json | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c3370fa4..bc2e0930 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -45,11 +45,12 @@ build: stage: build script: - npm run build + - mv dist ds4 cache: <<: *global_cache artifacts: paths: - - dist + - ds4 expire_in: 1 week deploy: @@ -58,7 +59,7 @@ deploy: dependencies: - build script: - - rsync --delete -az ./dist/ rsync://${DEPLOYMENT_USER}@${DEPLOYMENT_SERVER}:${DEPLOYMENT_PATH} + - rsync --delete -az ./ds4/ rsync://${DEPLOYMENT_USER}@${DEPLOYMENT_SERVER}:${DEPLOYMENT_PATH} environment: name: production url: https://vtt.f3l.de/ diff --git a/src/system.json b/src/system.json index 3929e3ab..43f2245b 100644 --- a/src/system.json +++ b/src/system.json @@ -22,7 +22,7 @@ "gridUnits": "m", "primaryTokenAttribute": "combatValues.hitPoints.current", "url": "https://git.f3l.de/dungeonslayers/ds4", - "manifest": "https://git.f3l.de/dungeonslayers/ds4/-/blob/master/src/system.json", - "download": "https://git.f3l.de/dungeonslayers/ds4/-/archive/master/ds4-master.zip", + "manifest": "https://git.f3l.de/dungeonslayers/ds4/-/raw/latest/src/system.json?inline=false", + "download": "https://git.f3l.de/dungeonslayers/ds4/-/jobs/artifacts/latest/download?job=build", "license": "MIT" } From 6d02f1623a9b7cc8ede66057150bd384203a6b67 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Wed, 6 Jan 2021 01:30:21 +0100 Subject: [PATCH 2/6] reference a version tag in the download url --- src/system.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system.json b/src/system.json index 43f2245b..a57664c3 100644 --- a/src/system.json +++ b/src/system.json @@ -22,7 +22,7 @@ "gridUnits": "m", "primaryTokenAttribute": "combatValues.hitPoints.current", "url": "https://git.f3l.de/dungeonslayers/ds4", - "manifest": "https://git.f3l.de/dungeonslayers/ds4/-/raw/latest/src/system.json?inline=false", - "download": "https://git.f3l.de/dungeonslayers/ds4/-/jobs/artifacts/latest/download?job=build", + "manifest": "https://git.f3l.de/dungeonslayers/ds4/-/raw/master/src/system.json?inline=false", + "download": "https://git.f3l.de/dungeonslayers/ds4/-/jobs/artifacts/0.1.0/download?job=build", "license": "MIT" } From b4f697f9cc1dee8b4604a56d9ed3e8bfeae99750 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Wed, 6 Jan 2021 01:31:23 +0100 Subject: [PATCH 3/6] format gulpfile --- gulpfile.js | 858 ++++++++++++++++++++++++++-------------------------- 1 file changed, 429 insertions(+), 429 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 83aa3820..dc62e8b7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,429 +1,429 @@ -const gulp = require("gulp"); -const fs = require("fs-extra"); -const path = require("path"); -const chalk = require("chalk"); -const archiver = require("archiver"); -const stringify = require("json-stringify-pretty-compact"); -const typescript = require("typescript"); - -const ts = require("gulp-typescript"); -const less = require("gulp-less"); -const sass = require("gulp-sass"); -const git = require("gulp-git"); - -const argv = require("yargs").argv; - -sass.compiler = require("sass"); - -function getConfig() { - const configPath = path.resolve(process.cwd(), "foundryconfig.json"); - let config; - - if (fs.existsSync(configPath)) { - config = fs.readJSONSync(configPath); - return config; - } else { - return; - } -} - -function getManifest() { - const json = {}; - - if (fs.existsSync("src")) { - json.root = "src"; - } else { - json.root = "dist"; - } - - const modulePath = path.join(json.root, "module.json"); - const systemPath = path.join(json.root, "system.json"); - - if (fs.existsSync(modulePath)) { - json.file = fs.readJSONSync(modulePath); - json.name = "module.json"; - } else if (fs.existsSync(systemPath)) { - json.file = fs.readJSONSync(systemPath); - json.name = "system.json"; - } else { - return; - } - - return json; -} - -/** - * TypeScript transformers - * @returns {typescript.TransformerFactory} - */ -function createTransformer() { - /** - * @param {typescript.Node} node - */ - function shouldMutateModuleSpecifier(node) { - if (!typescript.isImportDeclaration(node) && !typescript.isExportDeclaration(node)) return false; - if (node.moduleSpecifier === undefined) return false; - if (!typescript.isStringLiteral(node.moduleSpecifier)) return false; - if (!node.moduleSpecifier.text.startsWith("./") && !node.moduleSpecifier.text.startsWith("../")) return false; - if (path.extname(node.moduleSpecifier.text) !== "") return false; - return true; - } - - /** - * Transforms import/export declarations to append `.js` extension - * @param {typescript.TransformationContext} context - */ - function importTransformer(context) { - return (node) => { - /** - * @param {typescript.Node} node - */ - function visitor(node) { - if (shouldMutateModuleSpecifier(node)) { - if (typescript.isImportDeclaration(node)) { - const newModuleSpecifier = typescript.createLiteral(`${node.moduleSpecifier.text}.js`); - return typescript.updateImportDeclaration( - node, - node.decorators, - node.modifiers, - node.importClause, - newModuleSpecifier - ); - } else if (typescript.isExportDeclaration(node)) { - const newModuleSpecifier = typescript.createLiteral(`${node.moduleSpecifier.text}.js`); - return typescript.updateExportDeclaration( - node, - node.decorators, - node.modifiers, - node.exportClause, - newModuleSpecifier - ); - } - } - return typescript.visitEachChild(node, visitor, context); - } - - return typescript.visitNode(node, visitor); - }; - } - - return importTransformer; -} - -const tsConfig = ts.createProject("tsconfig.json", { - getCustomTransformers: (_program) => ({ - after: [createTransformer()], - }), -}); - -/********************/ -/* BUILD */ -/********************/ - -/** - * Build TypeScript - */ -function buildTS() { - 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 - */ -function buildSASS() { - return gulp.src("src/*.scss").pipe(sass().on("error", sass.logError)).pipe(gulp.dest("dist")); -} - -/** - * Copy static files - */ -async function copyFiles() { - const statics = ["lang", "fonts", "assets", "templates", "module.json", "system.json", "template.json"]; - try { - for (const file of statics) { - if (fs.existsSync(path.join("src", file))) { - await fs.copy(path.join("src", file), path.join("dist", file)); - } - } - return Promise.resolve(); - } catch (err) { - Promise.reject(err); - } -} - -/** - * Watch for changes for each build step - */ -function buildWatch() { - gulp.watch("src/**/*.ts", { ignoreInitial: false }, buildTS); - gulp.watch("src/**/*.less", { ignoreInitial: false }, buildLess); - gulp.watch("src/**/*.scss", { ignoreInitial: false }, buildSASS); - gulp.watch(["src/fonts", "src/lang", "src/templates", "src/*.json"], { ignoreInitial: false }, copyFiles); -} - -/********************/ -/* CLEAN */ -/********************/ - -/** - * Remove built files from `dist` folder - * while ignoring source files - */ -async function clean() { - const name = path.basename(path.resolve(".")); - const files = []; - - // If the project uses TypeScript - if (fs.existsSync(path.join("src", `${name}.ts`))) { - files.push( - "lang", - "templates", - "assets", - "module", - `${name}.js`, - "module.json", - "system.json", - "template.json" - ); - } - - // If the project uses Less or SASS - if (fs.existsSync(path.join("src", `${name}.less`)) || fs.existsSync(path.join("src", `${name}.scss`))) { - files.push("fonts", `${name}.css`); - } - - console.log(" ", chalk.yellow("Files to clean:")); - console.log(" ", chalk.blueBright(files.join("\n "))); - - // Attempt to remove the files - try { - for (const filePath of files) { - await fs.remove(path.join("dist", filePath)); - } - return Promise.resolve(); - } catch (err) { - Promise.reject(err); - } -} - -/********************/ -/* LINK */ -/********************/ - -/** - * Link build to User Data folder - */ -async function linkUserData() { - const name = path.basename(path.resolve(".")); - const config = fs.readJSONSync("foundryconfig.json"); - - let destDir; - try { - if ( - fs.existsSync(path.resolve(".", "dist", "module.json")) || - fs.existsSync(path.resolve(".", "src", "module.json")) - ) { - destDir = "modules"; - } else if ( - fs.existsSync(path.resolve(".", "dist", "system.json")) || - fs.existsSync(path.resolve(".", "src", "system.json")) - ) { - destDir = "systems"; - } else { - throw Error(`Could not find ${chalk.blueBright("module.json")} or ${chalk.blueBright("system.json")}`); - } - - let linkDir; - if (config.dataPath) { - if (!fs.existsSync(path.join(config.dataPath, "Data"))) - throw Error("User Data path invalid, no Data directory found"); - - linkDir = path.join(config.dataPath, "Data", destDir, name); - } else { - throw Error("No User Data path defined in foundryconfig.json"); - } - - if (argv.clean || argv.c) { - console.log(chalk.yellow(`Removing build in ${chalk.blueBright(linkDir)}`)); - - await fs.remove(linkDir); - } else if (!fs.existsSync(linkDir)) { - console.log(chalk.green(`Copying build to ${chalk.blueBright(linkDir)}`)); - await fs.symlink(path.resolve("./dist"), linkDir); - } - return Promise.resolve(); - } catch (err) { - Promise.reject(err); - } -} - -/*********************/ -/* 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 - */ -function updateManifest(cb) { - const packageJson = fs.readJSONSync("package.json"); - const config = getConfig(), - 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 (!rawURL || !repoURL) cb(Error(chalk.red("Repository URLs not configured in foundryconfig.json"))); - - try { - const version = argv.update || argv.u; - - /* Update version */ - - const versionMatch = /^(\d{1,}).(\d{1,}).(\d{1,})$/; - const currentVersion = manifest.file.version; - let targetVersion = ""; - - if (!version) { - cb(Error("Missing version number")); - } - - if (versionMatch.test(version)) { - targetVersion = version; - } else { - targetVersion = currentVersion.replace(versionMatch, (substring, major, minor, patch) => { - console.log(substring, Number(major) + 1, Number(minor) + 1, Number(patch) + 1); - if (version === "major") { - return `${Number(major) + 1}.0.0`; - } else if (version === "minor") { - return `${major}.${Number(minor) + 1}.0`; - } else if (version === "patch") { - return `${major}.${minor}.${Number(patch) + 1}`; - } else { - return ""; - } - }); - } - - if (targetVersion === "") { - return cb(Error(chalk.red("Error: Incorrect version arguments."))); - } - - if (targetVersion === currentVersion) { - return cb(Error(chalk.red("Error: Target version is identical to current version."))); - } - console.log(`Updating version number to '${targetVersion}'`); - - packageJson.version = targetVersion; - manifest.file.version = targetVersion; - - /* Update URLs */ - - 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; - - const prettyProjectJson = stringify(manifest.file, { - maxLength: 35, - indent: "\t", - }); - - fs.writeJSONSync("package.json", packageJson, { spaces: "\t" }); - fs.writeFileSync(path.join(manifest.root, manifest.name), prettyProjectJson, "utf8"); - - return cb(); - } catch (err) { - cb(err); - } -} - -function gitAdd() { - 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.watch = buildWatch; -exports.clean = clean; -exports.link = linkUserData; -exports.package = packageBuild; -exports.update = updateManifest; -exports.publish = gulp.series(clean, updateManifest, execBuild, packageBuild, execGit); +const gulp = require("gulp"); +const fs = require("fs-extra"); +const path = require("path"); +const chalk = require("chalk"); +const archiver = require("archiver"); +const stringify = require("json-stringify-pretty-compact"); +const typescript = require("typescript"); + +const ts = require("gulp-typescript"); +const less = require("gulp-less"); +const sass = require("gulp-sass"); +const git = require("gulp-git"); + +const argv = require("yargs").argv; + +sass.compiler = require("sass"); + +function getConfig() { + const configPath = path.resolve(process.cwd(), "foundryconfig.json"); + let config; + + if (fs.existsSync(configPath)) { + config = fs.readJSONSync(configPath); + return config; + } else { + return; + } +} + +function getManifest() { + const json = {}; + + if (fs.existsSync("src")) { + json.root = "src"; + } else { + json.root = "dist"; + } + + const modulePath = path.join(json.root, "module.json"); + const systemPath = path.join(json.root, "system.json"); + + if (fs.existsSync(modulePath)) { + json.file = fs.readJSONSync(modulePath); + json.name = "module.json"; + } else if (fs.existsSync(systemPath)) { + json.file = fs.readJSONSync(systemPath); + json.name = "system.json"; + } else { + return; + } + + return json; +} + +/** + * TypeScript transformers + * @returns {typescript.TransformerFactory} + */ +function createTransformer() { + /** + * @param {typescript.Node} node + */ + function shouldMutateModuleSpecifier(node) { + if (!typescript.isImportDeclaration(node) && !typescript.isExportDeclaration(node)) return false; + if (node.moduleSpecifier === undefined) return false; + if (!typescript.isStringLiteral(node.moduleSpecifier)) return false; + if (!node.moduleSpecifier.text.startsWith("./") && !node.moduleSpecifier.text.startsWith("../")) return false; + if (path.extname(node.moduleSpecifier.text) !== "") return false; + return true; + } + + /** + * Transforms import/export declarations to append `.js` extension + * @param {typescript.TransformationContext} context + */ + function importTransformer(context) { + return (node) => { + /** + * @param {typescript.Node} node + */ + function visitor(node) { + if (shouldMutateModuleSpecifier(node)) { + if (typescript.isImportDeclaration(node)) { + const newModuleSpecifier = typescript.createLiteral(`${node.moduleSpecifier.text}.js`); + return typescript.updateImportDeclaration( + node, + node.decorators, + node.modifiers, + node.importClause, + newModuleSpecifier, + ); + } else if (typescript.isExportDeclaration(node)) { + const newModuleSpecifier = typescript.createLiteral(`${node.moduleSpecifier.text}.js`); + return typescript.updateExportDeclaration( + node, + node.decorators, + node.modifiers, + node.exportClause, + newModuleSpecifier, + ); + } + } + return typescript.visitEachChild(node, visitor, context); + } + + return typescript.visitNode(node, visitor); + }; + } + + return importTransformer; +} + +const tsConfig = ts.createProject("tsconfig.json", { + getCustomTransformers: (_program) => ({ + after: [createTransformer()], + }), +}); + +/********************/ +/* BUILD */ +/********************/ + +/** + * Build TypeScript + */ +function buildTS() { + 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 + */ +function buildSASS() { + return gulp.src("src/*.scss").pipe(sass().on("error", sass.logError)).pipe(gulp.dest("dist")); +} + +/** + * Copy static files + */ +async function copyFiles() { + const statics = ["lang", "fonts", "assets", "templates", "module.json", "system.json", "template.json"]; + try { + for (const file of statics) { + if (fs.existsSync(path.join("src", file))) { + await fs.copy(path.join("src", file), path.join("dist", file)); + } + } + return Promise.resolve(); + } catch (err) { + Promise.reject(err); + } +} + +/** + * Watch for changes for each build step + */ +function buildWatch() { + gulp.watch("src/**/*.ts", { ignoreInitial: false }, buildTS); + gulp.watch("src/**/*.less", { ignoreInitial: false }, buildLess); + gulp.watch("src/**/*.scss", { ignoreInitial: false }, buildSASS); + gulp.watch(["src/fonts", "src/lang", "src/templates", "src/*.json"], { ignoreInitial: false }, copyFiles); +} + +/********************/ +/* CLEAN */ +/********************/ + +/** + * Remove built files from `dist` folder + * while ignoring source files + */ +async function clean() { + const name = path.basename(path.resolve(".")); + const files = []; + + // If the project uses TypeScript + if (fs.existsSync(path.join("src", `${name}.ts`))) { + files.push( + "lang", + "templates", + "assets", + "module", + `${name}.js`, + "module.json", + "system.json", + "template.json", + ); + } + + // If the project uses Less or SASS + if (fs.existsSync(path.join("src", `${name}.less`)) || fs.existsSync(path.join("src", `${name}.scss`))) { + files.push("fonts", `${name}.css`); + } + + console.log(" ", chalk.yellow("Files to clean:")); + console.log(" ", chalk.blueBright(files.join("\n "))); + + // Attempt to remove the files + try { + for (const filePath of files) { + await fs.remove(path.join("dist", filePath)); + } + return Promise.resolve(); + } catch (err) { + Promise.reject(err); + } +} + +/********************/ +/* LINK */ +/********************/ + +/** + * Link build to User Data folder + */ +async function linkUserData() { + const name = path.basename(path.resolve(".")); + const config = fs.readJSONSync("foundryconfig.json"); + + let destDir; + try { + if ( + fs.existsSync(path.resolve(".", "dist", "module.json")) || + fs.existsSync(path.resolve(".", "src", "module.json")) + ) { + destDir = "modules"; + } else if ( + fs.existsSync(path.resolve(".", "dist", "system.json")) || + fs.existsSync(path.resolve(".", "src", "system.json")) + ) { + destDir = "systems"; + } else { + throw Error(`Could not find ${chalk.blueBright("module.json")} or ${chalk.blueBright("system.json")}`); + } + + let linkDir; + if (config.dataPath) { + if (!fs.existsSync(path.join(config.dataPath, "Data"))) + throw Error("User Data path invalid, no Data directory found"); + + linkDir = path.join(config.dataPath, "Data", destDir, name); + } else { + throw Error("No User Data path defined in foundryconfig.json"); + } + + if (argv.clean || argv.c) { + console.log(chalk.yellow(`Removing build in ${chalk.blueBright(linkDir)}`)); + + await fs.remove(linkDir); + } else if (!fs.existsSync(linkDir)) { + console.log(chalk.green(`Copying build to ${chalk.blueBright(linkDir)}`)); + await fs.symlink(path.resolve("./dist"), linkDir); + } + return Promise.resolve(); + } catch (err) { + Promise.reject(err); + } +} + +/*********************/ +/* 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 + */ +function updateManifest(cb) { + const packageJson = fs.readJSONSync("package.json"); + const config = getConfig(), + 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 (!rawURL || !repoURL) cb(Error(chalk.red("Repository URLs not configured in foundryconfig.json"))); + + try { + const version = argv.update || argv.u; + + /* Update version */ + + const versionMatch = /^(\d{1,}).(\d{1,}).(\d{1,})$/; + const currentVersion = manifest.file.version; + let targetVersion = ""; + + if (!version) { + cb(Error("Missing version number")); + } + + if (versionMatch.test(version)) { + targetVersion = version; + } else { + targetVersion = currentVersion.replace(versionMatch, (substring, major, minor, patch) => { + console.log(substring, Number(major) + 1, Number(minor) + 1, Number(patch) + 1); + if (version === "major") { + return `${Number(major) + 1}.0.0`; + } else if (version === "minor") { + return `${major}.${Number(minor) + 1}.0`; + } else if (version === "patch") { + return `${major}.${minor}.${Number(patch) + 1}`; + } else { + return ""; + } + }); + } + + if (targetVersion === "") { + return cb(Error(chalk.red("Error: Incorrect version arguments."))); + } + + if (targetVersion === currentVersion) { + return cb(Error(chalk.red("Error: Target version is identical to current version."))); + } + console.log(`Updating version number to '${targetVersion}'`); + + packageJson.version = targetVersion; + manifest.file.version = targetVersion; + + /* Update URLs */ + + 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; + + const prettyProjectJson = stringify(manifest.file, { + maxLength: 35, + indent: "\t", + }); + + fs.writeJSONSync("package.json", packageJson, { spaces: "\t" }); + fs.writeFileSync(path.join(manifest.root, manifest.name), prettyProjectJson, "utf8"); + + return cb(); + } catch (err) { + cb(err); + } +} + +function gitAdd() { + 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.watch = buildWatch; +exports.clean = clean; +exports.link = linkUserData; +exports.package = packageBuild; +exports.update = updateManifest; +exports.publish = gulp.series(clean, updateManifest, execBuild, packageBuild, execGit); From fed3209c5803b5d10a004102b7059576585a3379 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Wed, 6 Jan 2021 03:22:25 +0100 Subject: [PATCH 4/6] update the readme --- README.md | 73 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 8119bbdb..4222e363 100644 --- a/README.md +++ b/README.md @@ -3,50 +3,89 @@ An implementation of the Dungeonslayers 4 game system for [Foundry Virtual Tabletop](http://foundryvtt.com). -## Prerequisites +This system provides character sheet support for Actors and Items and mechanical +support for dice and rules necessary to +play games of Dungeponslayers 4. -In order to build this system, a recent version of `npm` is required. +## Installation -## Building +To install and use the Dungeonslayers 4 system for Foundry Virtual Tabletop, +simply paste the following URL into the **Install System** dialog on the Setup +menu of the application. -To build the system, first install all required dependencies: +https://git.f3l.de/dungeonslayers/ds4/-/raw/master/src/system.json?inline=false + +## Development + +### Prerequisits + +In order to build this system, recent versions of `node` and `npm` are required. +We recommend using the latest lts version of `node`, which is `v14.15.4` at the +time of writing. If you use `nvm` to manage your `node` versions, you can simply +run +``` +nvm install +``` + +in the project's root directory. + +You also need to install the the project's dependencies. To do so, run ``` npm install ``` -Then build the project by running +### Building + +You can build the project by running ``` npm run build ``` -If you'd like the built system to be automatically linked to your local Foundry -VTT installation's data folder, add a file called `foundryconfig.json` to the -project root with the following contents: +Alternatively, you can run + +``` +npm run build:watch +``` + +to watch for changes and automatically build as necessary. + +### Linking the built system to Foundry VTT + +In order to provide a fluent development experience, it is recommended to link +the built system to your local Foundry VTT installation's data folder. In order +to do so, first add a file called `foundryconfig.json` to the project root with +the following content: ``` { - "dataPath": "//.local/share/FoundryVTT", - "repository": "", - "rawURL": "" + "dataPath": "/.local/share/FoundryVTT" } ``` +On platforms other than Linux you need to adjust the path accordingly. + Then run ``` npm run link ``` -If you want the system to be continuously build upon every saved change, just -run +### Running the tests + +You can run the tests with the following command: ``` -npm run build:watch +npm test ``` -# Licensing +## Contributing + +Code and content contributions are accepted. Please feel free to submit issues +to the issue tracker or submit merge requests for code changes. + +## Licensing Dungeonslayers (© Christian Kennig) is licensed under [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/de/deed.en). @@ -56,5 +95,5 @@ CC BY-NC-SA 3.0. Hence the modified icons are also published under this license. A copy of this license can be found under [src/assets/official/LICENSE](src/assets/official/LICENSE). -The rest of this project is licensed under the MIT License, a copy of which can -be found under [LICENSE](LICENSE). +The software component of this project is licensed under the MIT License, a copy +of which can be found under [LICENSE](LICENSE). From 6e363b3a02c5b9211f471063fd7e32f0bfe17120 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Wed, 6 Jan 2021 14:48:48 +0100 Subject: [PATCH 5/6] add bug report issue template and improve feature request --- .gitlab/issue_templates/Bug Report.md | 0 .gitlab/issue_templates/Feature Request.md | 12 ++++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 .gitlab/issue_templates/Bug Report.md diff --git a/.gitlab/issue_templates/Bug Report.md b/.gitlab/issue_templates/Bug Report.md new file mode 100644 index 00000000..e69de29b diff --git a/.gitlab/issue_templates/Feature Request.md b/.gitlab/issue_templates/Feature Request.md index f60644d2..d6dbe30b 100644 --- a/.gitlab/issue_templates/Feature Request.md +++ b/.gitlab/issue_templates/Feature Request.md @@ -1,9 +1,13 @@ -# Description +# Story As a …, I want … so that … +# Description + +Please add a more detailed description of the feature here. + # Acceptance criteria -* Criterion 1 -* Criterion 2 -* … +1. Criterion 1 +2. Criterion 2 +3. … From f40efedcd376ef2fd24c34785f7924efb2d2bb88 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Wed, 6 Jan 2021 14:56:50 +0100 Subject: [PATCH 6/6] add bug report template --- .gitlab/issue_templates/Bug Report.md | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.gitlab/issue_templates/Bug Report.md b/.gitlab/issue_templates/Bug Report.md index e69de29b..c209b177 100644 --- a/.gitlab/issue_templates/Bug Report.md +++ b/.gitlab/issue_templates/Bug Report.md @@ -0,0 +1,29 @@ +# Description + +Please describe the issue. + +# Steps to Reproduce + +1. ... +2. ... +3. ... + +# Expected Behavior + +Please describe the expected behavior. + +# Actual Behavior + +Please describe the actual behavior. + +# Additional Details + +These are optional, please add them if it makes sense. + +- ![Screenshot]() +- [Logfile]() +- ... + +# Possible Solutions + +If you have any suggestions on how to solve the issue, please add them here.