All checks were successful
Lint / pre-commit Linting (push) Successful in 25s
225 lines
6.4 KiB
JavaScript
225 lines
6.4 KiB
JavaScript
const { ScreepsAPI } = require("screeps-api");
|
|
const core = require("@actions/core");
|
|
const fs = require("fs");
|
|
const { glob } = require("glob");
|
|
const path = require("path");
|
|
|
|
/**
|
|
* Replaces placeholder strings in content with dynamic values.
|
|
*
|
|
* @param {string} content
|
|
* @param {string} hostname
|
|
* @returns {string}
|
|
*/
|
|
function replacePlaceholders(content, hostname) {
|
|
const deployTime = new Date().toISOString();
|
|
const gitHash = process.env.GITHUB_SHA;
|
|
const gitRef = process.env.GITHUB_REF;
|
|
|
|
core.info("Replacing placeholders:");
|
|
core.info(` GITHUB_SHA: ${gitHash}`);
|
|
core.info(` GITHUB_REF: ${gitRef}`);
|
|
core.info(` deployTime: ${deployTime}`);
|
|
core.info(` hostname: ${hostname}`);
|
|
|
|
return content
|
|
.replace(/{{gitHash}}/g, gitHash)
|
|
.replace(/{{gitRef}}/g, gitRef)
|
|
.replace(/{{deployTime}}/g, deployTime)
|
|
.replace(/{{hostname}}/g, hostname);
|
|
}
|
|
|
|
/**
|
|
* Replaces placeholders in files matched by glob.
|
|
*
|
|
* @param {string} pattern
|
|
* @param {string} [prefix]
|
|
* @param {string} hostname
|
|
* @returns {Promise<string[]>}
|
|
*/
|
|
function readReplaceAndWriteFiles(pattern, prefix, hostname) {
|
|
return new Promise((resolve, reject) => {
|
|
const globPattern = prefix ? path.join(prefix, pattern) : pattern;
|
|
|
|
glob(globPattern, (err, files) => {
|
|
if (err) return reject(err);
|
|
|
|
if (!files.length) {
|
|
core.warning(
|
|
`No files matched for placeholder replacement: ${globPattern}`,
|
|
);
|
|
return resolve([]);
|
|
}
|
|
|
|
core.info(`📝 Matched files for replacement:`);
|
|
files.forEach((file) => core.info(` - ${file}`));
|
|
|
|
const promises = files.map((file) =>
|
|
fs.promises
|
|
.readFile(file, "utf8")
|
|
.then((content) => {
|
|
content = replacePlaceholders(content, hostname);
|
|
return fs.promises.writeFile(file, content);
|
|
})
|
|
.then(() => {
|
|
core.info(`Replaced placeholders in file: ${file}`);
|
|
}),
|
|
);
|
|
|
|
Promise.all(promises)
|
|
.then(() => {
|
|
core.info(
|
|
`Successfully replaced placeholders in ${files.length} file(s).`,
|
|
);
|
|
resolve(files);
|
|
})
|
|
.catch(reject);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reads files into a dictionary of key → content.
|
|
*
|
|
* @param {string} pattern
|
|
* @param {string} prefix
|
|
* @returns {Promise<Object>}
|
|
*/
|
|
function readFilesIntoDict(pattern, prefix) {
|
|
return new Promise((resolve, reject) => {
|
|
const globPattern = prefix ? path.join(prefix, pattern) : pattern;
|
|
|
|
glob(globPattern, (err, files) => {
|
|
if (err) return reject(err);
|
|
|
|
if (!files.length) {
|
|
core.warning(`No files matched for upload: ${globPattern}`);
|
|
} else {
|
|
core.info(`📁 Matched files for upload:`);
|
|
files.forEach((file) => core.info(` - ${file}`));
|
|
}
|
|
|
|
const fileDict = {};
|
|
const readPromises = files.map((file) =>
|
|
fs.promises.readFile(file, "utf8").then((content) => {
|
|
let key = file;
|
|
if (prefix && file.startsWith(prefix)) {
|
|
key = key.slice(prefix.length);
|
|
}
|
|
key = path.basename(key, path.extname(key));
|
|
fileDict[key] = content;
|
|
}),
|
|
);
|
|
|
|
Promise.all(readPromises)
|
|
.then(() => resolve(fileDict))
|
|
.catch(reject);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Validates provided credentials.
|
|
*
|
|
* @param {string} token
|
|
* @param {string} username
|
|
* @param {string} password
|
|
* @returns {string|null}
|
|
*/
|
|
function validateAuthentication(token, username, password) {
|
|
if (token && (username || password)) {
|
|
return "Token is defined along with username and/or password.";
|
|
}
|
|
if (!token && (!username || !password)) {
|
|
return "Username and password must both be defined if token is not used.";
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Main logic for uploading code to Screeps.
|
|
*/
|
|
function postCode() {
|
|
core.info("🟢 Starting Screeps upload action...");
|
|
|
|
const protocol = core.getInput("protocol") || "https";
|
|
const hostname = core.getInput("hostname") || "screeps.com";
|
|
const port = core.getInput("port") || "443";
|
|
const path = core.getInput("path") || "/";
|
|
const token = core.getInput("token") || undefined;
|
|
const username = core.getInput("username") || undefined;
|
|
const password = core.getInput("password") || undefined;
|
|
const prefix = core.getInput("source-prefix");
|
|
const pattern = core.getInput("pattern") || "*.js";
|
|
const branch = core.getInput("branch") || "default";
|
|
const gitReplace = core.getInput("git-replace") || null;
|
|
|
|
const login_arguments = {
|
|
token,
|
|
username,
|
|
password,
|
|
protocol,
|
|
hostname,
|
|
port,
|
|
path,
|
|
};
|
|
|
|
core.info("🔧 Inputs:");
|
|
core.info(` prefix: ${prefix}`);
|
|
core.info(` pattern: ${pattern}`);
|
|
core.info(` branch: ${branch}`);
|
|
core.info(` gitReplace: ${gitReplace}`);
|
|
|
|
const errorMessage = validateAuthentication(token, username, password);
|
|
if (errorMessage) {
|
|
core.setFailed(errorMessage);
|
|
return Promise.reject(new Error(errorMessage));
|
|
}
|
|
|
|
const replacePromise = gitReplace
|
|
? readReplaceAndWriteFiles(gitReplace, prefix, hostname)
|
|
: Promise.resolve();
|
|
|
|
return replacePromise
|
|
.then(() => readFilesIntoDict(pattern, prefix))
|
|
.then((files_to_push) => {
|
|
const fileCount = Object.keys(files_to_push).length;
|
|
core.info(`📦 Files prepared for upload: ${fileCount}`);
|
|
|
|
if (fileCount === 0) {
|
|
core.warning("No files were found to upload. Exiting.");
|
|
return;
|
|
}
|
|
|
|
core.info(`⬆️ Uploading to branch '${branch}':`);
|
|
Object.keys(files_to_push).forEach((key) => {
|
|
core.info(` - ${key}`);
|
|
});
|
|
|
|
const api = new ScreepsAPI(login_arguments);
|
|
|
|
if (token) {
|
|
return api.code.set(branch, files_to_push).then((response) => {
|
|
core.info(JSON.stringify(response, null, 2));
|
|
core.info(`✅ Code uploaded to branch '${branch}' using token.`);
|
|
});
|
|
} else {
|
|
core.info(`🔐 Logging in as user '${username}'...`);
|
|
return api
|
|
.auth(username, password, login_arguments)
|
|
.then(() => api.code.set(branch, files_to_push))
|
|
.then(() => {
|
|
core.info(`✅ Code uploaded to branch '${branch}' via basic auth.`);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Kick off the process and ensure failures are surfaced
|
|
postCode().catch((err) => {
|
|
core.setFailed(err.message || err);
|
|
});
|
|
|
|
core.info(`✅ Final Code uploaded to branch via basic auth.`);
|
|
core.debug(`✅ DEBUG Final Code uploaded to branch via basic auth. DEBUG`);
|