diff --git a/dist/index.js b/dist/index.js index 0962238..3aebaec 100644 --- a/dist/index.js +++ b/dist/index.js @@ -34366,6 +34366,77 @@ const main_1 = __importDefault(__nccwpck_require__(1730)); }); +/***/ }), + +/***/ 5620: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.defaultConfig = exports.defaultPullRequest = exports.defaultCommit = exports.defaultAuthor = exports.defaultImage = exports.defaultPackage = void 0; +exports.defaultPackage = { + manager: "auto", + global: false, + dev: false, +}; +exports.defaultImage = { + url: "https://banners.beyondco.de/{title}.png", + parameters: { + pattern: "topography", + style: "style_2", + fontSize: "100px", + md: "1", + showWatermark: "1", + }, +}; +exports.defaultAuthor = { + name: "github-actions", + email: "github-actions@github.com", +}; +exports.defaultCommit = { + branch: "preview/banner-{random}", + title: "docs(preview): Update repository banner image", + author: exports.defaultAuthor, +}; +exports.defaultPullRequest = { + title: "Update repository banner image", + labels: ["preview"], +}; +exports.defaultConfig = { + readme: "README.md", + package: exports.defaultPackage, + image: exports.defaultImage, + repository: { + commit: exports.defaultCommit, + pullRequest: exports.defaultPullRequest, + }, +}; + + +/***/ }), + +/***/ 1053: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.reservedWords = void 0; +exports.reservedWords = [ + "GitHub", + "BitBucket", + "GitLab", + "JSON", + "via", + "by", + "with", + "for", + "a", + "at", +]; + + /***/ }), /***/ 1730: @@ -34384,33 +34455,44 @@ const outputs_1 = __nccwpck_require__(8595); const packageManagers_1 = __nccwpck_require__(2453); const strings_1 = __nccwpck_require__(3063); const config_1 = __nccwpck_require__(7799); +const defaults_1 = __nccwpck_require__(5620); const previewUpdater = async () => { // Inputs const { token, configPath } = (0, inputs_1.parse)(); + // Credentials + const credentials = { + owner: github_1.context.repo.owner, + repo: github_1.context.repo.repo, + }; + // API + const github = (0, github_1.getOctokit)(token); // Load Config + const _repo = new repository_1.Repository({ + repository: credentials, + }, github); const config = await (0, config_1.readConfig)({ directory: (0, filesystem_1.cwd)(), - repository: { - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, - }, - }, configPath); + repository: credentials, + }, configPath, _repo); // Read names - const packageData = (0, packageManagers_1.getPackageManager)(config); - config.image.parameters.packageName ||= packageData.name; - config.image.parameters.title ||= (0, strings_1.titleCase)(config.repository.repo); - config.image.parameters.description ||= - packageData.description || config.repository.owner; + const packageLock = (0, packageManagers_1.getPackageManager)(config); + config.readme ||= defaults_1.defaultConfig.readme || "README.md"; + config.package ||= defaults_1.defaultPackage; + config.data ||= {}; + config.package.name ||= packageLock.name; + config.data.title ||= (0, strings_1.titleCase)(config.repository?.repo); + config.data.description ||= + packageLock.description || config.repository?.owner; // Show working directory (0, core_1.info)(`Working directory: ${config.directory}`); // Authenticate - const repo = new repository_1.Repository(config, (0, github_1.getOctokit)(token)); + const repo = new repository_1.Repository(config, github); await repo.authenticate(); // Read file - const content = (0, filesystem_1.readFile)(config, config.path.readme); - const preview = (0, preview_1.setPreview)(content, config, packageData); + const content = (0, filesystem_1.readFile)(config, config.readme); + const preview = (0, preview_1.setPreview)(content, config, packageLock); if (content === preview) { - (0, core_1.info)(`File "${config.path.readme}" is up to date`); + (0, core_1.info)(`File "${config.readme}" is up to date`); return; } // Checkout branch @@ -34418,8 +34500,8 @@ const previewUpdater = async () => { (0, core_1.info)(`Checkout ${branchExists ? "existing" : "new"} branch named "${repo.branchName()}"`); await repo.checkoutBranch(!branchExists); // Write a file - (0, core_1.info)(`Update readme in "${config.path.readme}" file`); - (0, filesystem_1.writeFile)(config, config.path.readme, preview); + (0, core_1.info)(`Update readme in "${config.readme}" file`); + (0, filesystem_1.writeFile)(config, config.readme, preview); // Stage and commit changes await repo.stage(); await repo.commit(); @@ -34429,69 +34511,19 @@ const previewUpdater = async () => { // Variables const pullRequestNumber = pullRequest.data.number; const pullRequestUrl = pullRequest.data.html_url; - if (config.repository.pullRequest.assignees.length > 0) { - await repo.assignee(pullRequestNumber, config.repository.pullRequest.assignees); - } - if (config.repository.pullRequest.labels.length > 0) { - await repo.addLabels(pullRequestNumber, config.repository.pullRequest.labels); - } + // Set labels and assignees + await repo.assignee(pullRequestNumber, config.repository?.pullRequest?.assignees || + defaults_1.defaultPullRequest.assignees || + []); + await repo.addLabels(pullRequestNumber, config.repository?.pullRequest?.labels || + defaults_1.defaultPullRequest.labels || + []); (0, core_1.info)(`Preview created in Pull Request #${pullRequestNumber}: ${pullRequestUrl}`); (0, outputs_1.setOutputs)(repo.branchName(), pullRequestNumber, pullRequestUrl); }; exports["default"] = previewUpdater; -/***/ }), - -/***/ 7899: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.defaultConfig = void 0; -exports.defaultConfig = { - directory: undefined, - path: { - readme: "README.md", - }, - image: { - url: "https://banners.beyondco.de/{title}.png", - parameters: { - pattern: "topography", - style: "style_2", - fontSize: "100px", - icon: undefined, - packageManager: "auto", - packageGlobal: false, - packageDev: false, - packageName: undefined, - title: undefined, - description: undefined, - }, - }, - repository: { - owner: undefined, - repo: undefined, - commit: { - branch: "preview/banner-{random}", - title: "docs(preview): Update preview", - body: undefined, - author: { - name: "github-actions", - email: "github-actions@github.com", - }, - }, - pullRequest: { - title: "Update preview", - body: undefined, - assignees: [], - labels: ["preview"], - }, - }, -}; - - /***/ }), /***/ 7799: @@ -34534,33 +34566,32 @@ var __importStar = (this && this.__importStar) || (function () { })(); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.readRemoteConfig = exports.readConfig = void 0; -const config_1 = __nccwpck_require__(7899); const yaml = __importStar(__nccwpck_require__(4281)); const filesystem_1 = __nccwpck_require__(9742); const merge_1 = __nccwpck_require__(2221); const core_1 = __nccwpck_require__(7484); const url = __importStar(__nccwpck_require__(3136)); -const readConfig = async (config, userConfigPath) => { +const defaults_1 = __nccwpck_require__(5620); +const readConfig = async (config, userConfigPath, repo) => { const content = (0, filesystem_1.readFile)(config, userConfigPath); - const remoteConfig = await (0, exports.readRemoteConfig)(config.repository?.owner, userConfigPath); + const remoteConfig = await (0, exports.readRemoteConfig)(repo, userConfigPath); if (content === "") { - return (0, merge_1.merge)(config_1.defaultConfig, remoteConfig, config); + return (0, merge_1.merge)(defaults_1.defaultConfig, remoteConfig, config); } const userConfig = yaml.load(content); - return (0, merge_1.merge)(config_1.defaultConfig, remoteConfig, userConfig, config); + return (0, merge_1.merge)(defaults_1.defaultConfig, remoteConfig, userConfig, config); }; exports.readConfig = readConfig; -const readRemoteConfig = async (owner, filename) => { +const readRemoteConfig = async (repo, filename) => { try { - if (owner === undefined) { + if (repo === undefined) { return {}; } - const url = `https://raw.githubusercontent.com/${owner}/.github/refs/heads/main/${filename}`; - const data = await (0, filesystem_1.readRemoteFile)(url); - if (data === "") { - return {}; + const response = await repo.getRawFile(filename); + if (response !== "") { + return yaml.load(response); } - return yaml.load(data); + return {}; } catch (error) { // @ts-expect-error @@ -34612,10 +34643,8 @@ var __importStar = (this && this.__importStar) || (function () { }; })(); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.writeFile = exports.readFile = exports.readRemoteFile = exports.fileExists = exports.cwd = void 0; +exports.writeFile = exports.readFile = exports.fileExists = exports.cwd = void 0; const fs = __importStar(__nccwpck_require__(3024)); -const core_1 = __nccwpck_require__(7484); -const node_https_1 = __nccwpck_require__(4708); const cwd = () => { const path = process.env.GITHUB_WORKSPACE; if (path === undefined) { @@ -34627,28 +34656,6 @@ exports.cwd = cwd; const filePath = (config, filename) => `${config.directory}/${filename}`; const fileExists = (config, filename) => fs.existsSync(filePath(config, filename)); exports.fileExists = fileExists; -const readRemoteFile = async (url) => { - return new Promise((resolve) => { - (0, node_https_1.get)(url, (res) => { - if (res.statusCode !== 200) { - (0, core_1.info)(`Failed to fetch ${url} with status code ${res.statusCode}`); - resolve(""); - return; - } - let data = ""; - res.on("data", (chunk) => { - data += chunk; - }); - res.on("end", () => { - resolve(data); - }); - }).on("error", (err) => { - (0, core_1.info)(`Failed to fetch ${url} with error: ${err.message}`); - resolve(""); - }); - }); -}; -exports.readRemoteFile = readRemoteFile; const readFile = (config, filename) => { if (!fs.existsSync(filePath(config, filename))) { return ""; @@ -34693,7 +34700,10 @@ const find = (dependencies, icons) => { } return undefined; }; -const detectIcon = (packageData) => { +const detectIcon = (image, packageData) => { + if (image?.parameters?.icon) { + return image.parameters.icon; + } if (packageData?.require !== undefined) { const phpIcon = find(packageData.require, exports.phpIcons); return phpIcon || exports.defaultPhpIcon; @@ -34717,8 +34727,8 @@ exports.detectIcon = detectIcon; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getImages = void 0; const packageManagers_1 = __nccwpck_require__(2453); -const strings_1 = __nccwpck_require__(3063); const icons_1 = __nccwpck_require__(5983); +const strings_1 = __nccwpck_require__(3063); const command = (manager, dev, global) => { switch (manager) { case "composer": @@ -34744,9 +34754,9 @@ const detectPackageManager = (config) => { return "none"; }; const packageManager = (config) => { - const global = config.image.parameters.packageGlobal; - const dev = config.image.parameters.packageDev; - let name = config.image.parameters.packageManager; + const global = config.package?.global || false; + const dev = config.package?.dev || false; + let name = config.package?.manager || "auto"; if (name === "none") { return ""; } @@ -34756,34 +34766,32 @@ const packageManager = (config) => { if (["composer", "npm", "yarn"].includes(name)) { return command(name, dev, global); } - return config.image.parameters.packageManager.trim(); + return name.trim(); }; -const packageName = (image) => { - if (image.packageManager === "none") { +const packageName = (data) => { + if (data?.manager === "none") { return ""; } - return image?.packageName || ""; + return data?.name || ""; }; const render = (config, packageData, theme) => { - const image = config.image.parameters; - const params = new URLSearchParams({ - theme: theme, - pattern: image.pattern, - style: image.style, - fontSize: image.fontSize, - images: image.icon || (0, icons_1.detectIcon)(packageData), - packageManager: packageManager(config), - packageName: packageName(image), - description: image.description || "", - md: "1", - showWatermark: "1", - }); - return (config.image.url.replace("{title}", (0, strings_1.encodeUri)(image.title)) + - "?" + - params.toString()); + let url = config.image?.url || ""; + const parameters = config.image?.parameters || {}; + parameters.theme = theme; + parameters.packageManager = packageManager(config); + parameters.packageName = packageName(config.package); + parameters.title ||= config.data?.title || ""; + parameters.description ||= config.data?.description || ""; + parameters.images = (0, icons_1.detectIcon)(config.image, packageData); + for (const [key, value] of Object.entries(parameters)) { + url = url.replace(`{${key}}`, (0, strings_1.encodeUri)(value)); + } + delete parameters.title; + const query = new URLSearchParams(parameters).toString(); + return `${url}?${query}`; }; const getImages = (config, packageData) => { - const title = config.image.parameters.title; + const title = config.data?.title; const light = render(config, packageData, "light"); const dark = render(config, packageData, "dark"); return ` @@ -34809,7 +34817,7 @@ exports.TOKEN = { env: "INPUT_TOKEN", }; exports.CONFIG_PATH = { - name: "configPath", + name: "config", env: "INPUT_CONFIG_PATH", defaultValue: ".github/preview-updater.yml", }; @@ -34900,7 +34908,7 @@ const strings_1 = __nccwpck_require__(3063); const hasHeader = (content) => content.match(/^#\s+/); const setPreview = (content, config, packageData) => { if (!hasHeader(content)) { - const title = (0, strings_1.titleCase)(config.image.parameters.title); + const title = (0, strings_1.titleCase)(config.data?.title); content = `# ${title}\n\n${content}`; } const images = (0, image_1.getImages)(config, packageData); @@ -34940,6 +34948,8 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.Repository = void 0; const processes_1 = __nccwpck_require__(1896); const strings_1 = __nccwpck_require__(3063); +const defaults_1 = __nccwpck_require__(5620); +const core_1 = __nccwpck_require__(7484); class Repository { constructor(config, octokit) { this._currentBranch = ""; @@ -34948,14 +34958,16 @@ class Repository { this._octokit = octokit; } async authenticate() { + const authorName = this._config.repository?.commit?.author?.name || defaults_1.defaultAuthor.name; + const authorEmail = this._config.repository?.commit?.author?.email || + defaults_1.defaultAuthor.email; try { - const author = this._config.repository.commit.author; - await (0, processes_1.exec)(`git config user.name "${author.name}"`); - await (0, processes_1.exec)(`git config user.email "${author.email}"`); + await (0, processes_1.exec)(`git config user.name "${authorName}"`); + await (0, processes_1.exec)(`git config user.email "${authorEmail}"`); } catch (error) { // @ts-expect-error - error.message = `Error authenticating user "${author.name}" with e-mail "${author.email}": ${error.message}`; + error.message = `Error authenticating user "${authorName}" with e-mail "${authorEmail}": ${error.message}`; throw error; } } @@ -34990,18 +35002,20 @@ class Repository { } async stage() { try { - await (0, processes_1.exec)(`git add ${this._config.path.readme}`); + await (0, processes_1.exec)(`git add ${this._config.readme}`); } catch (error) { // @ts-expect-error - error.message = `Error staging file "${this._config.path.readme}": ${error.message}`; + error.message = `Error staging file "${this._config.readme}": ${error.message}`; throw error; } } async commit() { try { - let message = this._config.repository.commit.title; - const body = this._config.repository.commit.body || ""; + let message = this._config.repository?.commit?.title || defaults_1.defaultCommit.title; + const body = this._config.repository?.commit?.body || + defaults_1.defaultCommit.body || + ""; if (body !== "") { message += `\n${body}`; } @@ -35009,7 +35023,7 @@ class Repository { } catch (error) { // @ts-expect-error - error.message = `Error committing file "${this._config.path.readme}": ${error.message}`; + error.message = `Error committing file "${this._config.readme}": ${error.message}`; throw error; } } @@ -35029,12 +35043,15 @@ class Repository { } async createPullRequest() { try { - const defaultBranch = await (0, processes_1.exec)(`git remote show origin | grep 'HEAD branch' | cut -d ' ' -f5`); - return this._octokit.rest.pulls.create({ - owner: this._config.repository.owner, - repo: this._config.repository.repo, - title: this._config.repository.pullRequest.title, - body: this._config.repository.pullRequest.body, + const defaultBranch = await this.defaultBranchName(); + return await this._octokit.rest.pulls.create({ + owner: this._config.repository?.owner, + repo: this._config.repository?.repo, + title: this._config.repository?.pullRequest?.title || + defaults_1.defaultPullRequest.title, + body: this._config.repository?.pullRequest?.body || + defaults_1.defaultPullRequest.body || + "", head: this.branchName(), base: defaultBranch, }); @@ -35047,9 +35064,12 @@ class Repository { } async assignee(issueNumber, assignees) { try { - return this._octokit.rest.issues.addAssignees({ - owner: this._config.repository.owner, - repo: this._config.repository.repo, + if (assignees.length === 0) { + return; + } + return await this._octokit.rest.issues.addAssignees({ + owner: this._config.repository?.owner, + repo: this._config.repository?.repo, issue_number: issueNumber, assignees: assignees, }); @@ -35062,9 +35082,12 @@ class Repository { } async addLabels(issueNumber, labels) { try { - return this._octokit.rest.issues.addLabels({ - owner: this._config.repository.owner, - repo: this._config.repository.repo, + if (labels.length === 0) { + return; + } + return await this._octokit.rest.issues.addLabels({ + owner: this._config.repository?.owner, + repo: this._config.repository?.repo, issue_number: issueNumber, labels, }); @@ -35075,12 +35098,40 @@ class Repository { throw error; } } + async getRawFile(filename) { + try { + const response = await this._octokit.rest.repos.getContent({ + owner: this._config.repository?.owner, + repo: ".github", + path: filename, + headers: { + Accept: "application/vnd.github.v3.raw", + }, + }); + if (response.status !== 200) { + return ""; + } + // @ts-expect-error + return response.data; + } + catch (error) { + // @ts-expect-error + (0, core_1.info)(error.message); + return ""; + } + } branchName() { if (this._currentBranch === "") { - this._currentBranch = this._config.repository.commit.branch.replace("{random}", (0, strings_1.randomString)()); + const branch = this._config.repository?.commit?.branch || + defaults_1.defaultCommit.branch || + "preview/{random}"; + this._currentBranch = branch.replace("{random}", (0, strings_1.randomString)()); } return this._currentBranch; } + async defaultBranchName() { + return await (0, processes_1.exec)(`git remote show origin | grep 'HEAD branch' | cut -d ' ' -f5`); + } } exports.Repository = Repository; @@ -35088,21 +35139,31 @@ exports.Repository = Repository; /***/ }), /***/ 3063: -/***/ ((__unused_webpack_module, exports) => { +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.randomString = exports.encodeUri = exports.removeImages = exports.titleCase = void 0; +const words_1 = __nccwpck_require__(1053); +const normalizeWords = (value) => { + for (const word of words_1.reservedWords) { + value = value.replace(new RegExp(`\\b${word}\\b`, "i"), word); + } + return value; +}; const titleCase = (title) => { if (title === "" || title === undefined) { return ""; } - return title + title = title .replace(/([A-Z])/g, "$1") .toLowerCase() .replace(/(^|\s|-|_)\S/g, (match) => match.toUpperCase()) - .replace(/[-_]/g, " "); + .replace(/[-_]/g, " ") + .trim(); + const normalized = normalizeWords(title); + return normalized.charAt(0).toUpperCase() + normalized.slice(1); }; exports.titleCase = titleCase; const removeImages = (content) => content @@ -35266,14 +35327,6 @@ module.exports = require("node:fs"); /***/ }), -/***/ 4708: -/***/ ((module) => { - -"use strict"; -module.exports = require("node:https"); - -/***/ }), - /***/ 7075: /***/ ((module) => {