2024-09-22 01:07:02 +02:00
|
|
|
const gulp = require('gulp');
|
|
|
|
const prefix = require('gulp-autoprefixer');
|
|
|
|
const sourcemaps = require('gulp-sourcemaps');
|
|
|
|
const sass = require('gulp-sass')(require('sass'));
|
|
|
|
const zip = require('gulp-zip');
|
2024-09-24 19:21:44 +02:00
|
|
|
const fs = require('fs');
|
2024-09-24 19:31:35 +02:00
|
|
|
const fetch = import('node-fetch');
|
2024-09-24 19:21:44 +02:00
|
|
|
const replace = require('gulp-replace');
|
|
|
|
const FormData = require('form-data');
|
|
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Export Tasks
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
exports.default = gulp.series(
|
|
|
|
compileScss,
|
|
|
|
watchUpdates
|
|
|
|
);
|
|
|
|
|
|
|
|
exports.build = gulp.series(
|
|
|
|
compileScss,
|
|
|
|
checkVersion,
|
|
|
|
ensureOutputDirExists,
|
|
|
|
packageCompendiums,
|
|
|
|
updateSystemJson,
|
|
|
|
zipRelease
|
|
|
|
);
|
|
|
|
|
|
|
|
exports.compile = gulp.series(
|
|
|
|
compileScss,
|
|
|
|
ensureOutputDirExists,
|
|
|
|
packageCompendiums,
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
exports.release = gulp.series(
|
|
|
|
exports.build,
|
|
|
|
uploadToPackageRegistry,
|
|
|
|
publishToFoundry
|
|
|
|
);
|
2024-09-22 01:07:02 +02:00
|
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Compile Sass
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
// Small error handler helper function.
|
|
|
|
function handleError(err) {
|
|
|
|
console.log(err.toString());
|
|
|
|
this.emit('end');
|
|
|
|
}
|
|
|
|
|
|
|
|
const SYSTEM_SCSS = ["scss/**/*.scss"];
|
|
|
|
function compileScss() {
|
|
|
|
// Configure options for sass output. For example, 'expanded' or 'nested'
|
|
|
|
let options = {
|
|
|
|
outputStyle: 'expanded'
|
|
|
|
};
|
|
|
|
return gulp.src(SYSTEM_SCSS)
|
|
|
|
.pipe(
|
2024-09-22 02:26:56 +02:00
|
|
|
sass(options)
|
2024-09-22 01:07:02 +02:00
|
|
|
.on('error', handleError)
|
|
|
|
)
|
|
|
|
.pipe(prefix({
|
|
|
|
cascade: false
|
|
|
|
}))
|
|
|
|
.pipe(gulp.dest("./css"))
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Watch Updates
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
function watchUpdates() {
|
|
|
|
gulp.watch(SYSTEM_SCSS, css);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Zip Release
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
function zipRelease() {
|
|
|
|
return gulp.src([
|
|
|
|
'./**/*',
|
|
|
|
'!./node_modules/**',
|
|
|
|
'!./.git/**',
|
|
|
|
'!./.gitignore',
|
|
|
|
'!./gulpfile.js',
|
|
|
|
'!./package-lock.json',
|
|
|
|
'!./package.json',
|
|
|
|
'!./scss/**/*',
|
|
|
|
'!./.github/**/*',
|
2024-09-24 19:21:44 +02:00
|
|
|
'!./.gitlab-ci.yml',
|
|
|
|
'!./README.md',
|
|
|
|
'!./compendiums/**/*',
|
|
|
|
'!./*.zip'
|
2024-09-22 01:07:02 +02:00
|
|
|
], { base: '.' })
|
2024-09-22 15:57:37 +02:00
|
|
|
.pipe(zip('kidsonbrooms.zip'))
|
2024-09-22 01:07:02 +02:00
|
|
|
.pipe(gulp.dest('.'));
|
|
|
|
}
|
|
|
|
|
2024-09-24 19:21:44 +02:00
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Version Check
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
function checkVersion(done) {
|
2024-09-24 19:37:22 +02:00
|
|
|
const Manifest = JSON.parse(fs.readFileSync('system.json'));
|
|
|
|
const manifestVersion = Manifest.version;
|
2024-09-24 19:21:44 +02:00
|
|
|
const gitTag = process.env.CI_COMMIT_TAG;
|
|
|
|
|
|
|
|
if (gitTag && manifestVersion !== gitTag) {
|
|
|
|
console.error(`Version mismatch between tag (${gitTag}) and manifest (${manifestVersion})!`);
|
|
|
|
process.exit(1);
|
|
|
|
} else {
|
|
|
|
console.log(`Version check passed: ${manifestVersion}`);
|
|
|
|
done();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Bundle Compendium
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
const { exec } = require('child_process');
|
|
|
|
|
|
|
|
function packageCompendiums(done) {
|
|
|
|
const packsDir = './compendiums'; // Adjust to your compendium source directory
|
|
|
|
const outputDir = './packs';
|
|
|
|
const moduleId = 'kidsonbrooms'; // Replace with your actual module ID
|
|
|
|
|
|
|
|
// Read all subdirectories in the packsDir
|
|
|
|
fs.readdir(packsDir, (err, files) => {
|
|
|
|
if (err) {
|
|
|
|
console.error(`Error reading directory ${packsDir}: ${err}`);
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Filter out files to get only directories
|
|
|
|
const folders = files.filter(file => fs.statSync(path.join(packsDir, file)).isDirectory());
|
|
|
|
|
|
|
|
if (folders.length === 0) {
|
|
|
|
console.log(`No compendium folders found in ${packsDir}`);
|
|
|
|
done();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let completed = 0;
|
|
|
|
folders.forEach(folder => {
|
|
|
|
const packName = folder; // Use the folder name as the pack name
|
|
|
|
const inputPath = path.join(packsDir, folder);
|
|
|
|
const command = `npx fvtt package pack --type System --id ${moduleId} -n "${packName}" --in "${inputPath}" --out "${outputDir}" --yaml`;
|
|
|
|
|
|
|
|
exec(command, (err, stdout, stderr) => {
|
|
|
|
if (err) {
|
|
|
|
console.error(`Error packaging compendium ${packName}:\n${stderr}`);
|
|
|
|
process.exit(1);
|
|
|
|
} else {
|
|
|
|
console.log(`Compendium ${packName} packaged successfully.`);
|
|
|
|
console.log(stdout);
|
|
|
|
completed++;
|
|
|
|
// When all compendiums have been processed, call done()
|
|
|
|
if (completed === folders.length) {
|
|
|
|
done();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Ensure Output Directory Exists
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
function ensureOutputDirExists() {
|
|
|
|
const outputDir = './packs';
|
|
|
|
if (!fs.existsSync(outputDir)) {
|
|
|
|
fs.mkdirSync(outputDir);
|
|
|
|
}
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Upload to Package Registry
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
async function uploadToPackageRegistry(done) {
|
|
|
|
const manifestFile = 'system.json';
|
|
|
|
const zipFile = process.env.ZIPFILE || 'kidsonbrooms.zip';
|
|
|
|
const packageRegistryUrl = process.env.PACKAGE_REGISTRY_URL;
|
|
|
|
const ciJobToken = process.env.CI_JOB_TOKEN;
|
|
|
|
|
|
|
|
if (!packageRegistryUrl || !ciJobToken) {
|
|
|
|
console.error('PACKAGE_REGISTRY_URL or CI_JOB_TOKEN is not defined.');
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Upload manifest file
|
|
|
|
const manifestUploadUrl = `${packageRegistryUrl}/${manifestFile}`;
|
|
|
|
console.log(`Uploading ${manifestFile} to ${manifestUploadUrl}`);
|
|
|
|
|
|
|
|
let response = await fetch(manifestUploadUrl, {
|
|
|
|
method: 'PUT',
|
|
|
|
headers: {
|
|
|
|
'JOB-TOKEN': ciJobToken,
|
|
|
|
'Content-Type': 'application/octet-stream',
|
|
|
|
},
|
|
|
|
body: fs.createReadStream(manifestFile),
|
|
|
|
});
|
|
|
|
|
|
|
|
if (response.ok) {
|
|
|
|
console.log(`Uploaded ${manifestFile} successfully.`);
|
|
|
|
} else {
|
|
|
|
console.error(`Failed to upload ${manifestFile}: ${response.statusText}`);
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Upload zip file
|
|
|
|
const zipUploadUrl = `${packageRegistryUrl}/${zipFile}`;
|
|
|
|
console.log(`Uploading ${zipFile} to ${zipUploadUrl}`);
|
|
|
|
|
|
|
|
response = await fetch(zipUploadUrl, {
|
|
|
|
method: 'PUT',
|
|
|
|
headers: {
|
|
|
|
'JOB-TOKEN': ciJobToken,
|
|
|
|
'Content-Type': 'application/octet-stream',
|
|
|
|
},
|
|
|
|
body: fs.createReadStream(zipFile),
|
|
|
|
});
|
|
|
|
|
|
|
|
if (response.ok) {
|
|
|
|
console.log(`Uploaded ${zipFile} successfully.`);
|
|
|
|
} else {
|
|
|
|
console.error(`Failed to upload ${zipFile}: ${response.statusText}`);
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
done();
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`Error uploading files: ${error.message}`);
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Publish to FoundryVTT
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
function publishToFoundry(done) {
|
|
|
|
const moduleManifestPath = 'system.json';
|
|
|
|
const moduleManifest = JSON.parse(fs.readFileSync(moduleManifestPath));
|
|
|
|
|
|
|
|
const id = moduleManifest.name;
|
|
|
|
const version = moduleManifest.version;
|
|
|
|
const compMin = moduleManifest.compatibility.minimum;
|
|
|
|
const compVer = moduleManifest.compatibility.verified;
|
|
|
|
const compMax = moduleManifest.compatibility.maximum;
|
|
|
|
const manifest = process.env.MANIFEST_RELEASE_URL || `https://gitlab.com/${process.env.CI_PROJECT_NAMESPACE}/${process.env.CI_PROJECT_NAME}/-/releases/${process.env.CI_COMMIT_TAG}/downloads/${moduleManifestPath}`;
|
|
|
|
const notes = `https://gitlab.com/${process.env.CI_PROJECT_NAMESPACE}/${process.env.CI_PROJECT_NAME}/-/tags/${process.env.CI_COMMIT_TAG}`;
|
|
|
|
|
|
|
|
const dryRun = process.env.dry_run === 'true';
|
2024-09-24 19:25:17 +02:00
|
|
|
const authToken = process.env.FOUNDRY_API_KEY;
|
2024-09-24 19:21:44 +02:00
|
|
|
|
|
|
|
if (!authToken) {
|
2024-09-24 19:25:17 +02:00
|
|
|
console.error('Foundry VTT API authentication token (FOUNDRY_API_KEY) is not defined.');
|
2024-09-24 19:21:44 +02:00
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Construct the payload
|
|
|
|
const payload = {
|
|
|
|
id: id,
|
|
|
|
release: {
|
|
|
|
version: version,
|
|
|
|
manifest: manifest,
|
|
|
|
notes: notes,
|
|
|
|
compatibility: {
|
|
|
|
minimum: compMin,
|
|
|
|
verified: compVer,
|
|
|
|
maximum: compMax,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
if (dryRun) {
|
|
|
|
payload['dry-run'] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send the POST request to Foundry VTT API
|
|
|
|
const response = fetch('https://api.foundryvtt.com/_api/packages/release', {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
Authorization: authToken,
|
|
|
|
},
|
|
|
|
body: JSON.stringify(payload),
|
|
|
|
});
|
|
|
|
|
|
|
|
const responseData = response.json();
|
|
|
|
|
|
|
|
if (responseData.status === 'success') {
|
|
|
|
console.log('Successfully published to Foundry VTT:');
|
|
|
|
console.log(JSON.stringify(responseData, null, 2));
|
|
|
|
done();
|
|
|
|
} else {
|
|
|
|
console.error('Failed to publish to Foundry VTT:');
|
|
|
|
console.error(JSON.stringify(responseData, null, 2));
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
/* Update systen.json with Download URL
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
|
|
|
|
function updateSystemJson(done) {
|
|
|
|
const ManifestPath = 'system.json';
|
|
|
|
const Manifest = JSON.parse(fs.readFileSync(ManifestPath));
|
|
|
|
const zipUrl = process.env.ZIPFILE_PERMALINK_URL || 'https://gitlab.com/wintermyst/kidsonbrooms/-/raw/master/kidsonbrooms.zip?inline=false';
|
|
|
|
|
|
|
|
Manifest.download = zipUrl;
|
|
|
|
|
|
|
|
fs.writeFileSync(ManifestPath, JSON.stringify(Manifest, null, 2));
|
|
|
|
console.log(`Updated module.json with download URL: ${zipUrl}`);
|
|
|
|
done();
|
|
|
|
}
|