@ethima/semantic-release-configuration
Version:
A shareable semantic release configuration supporting a range of languages and platforms supported by the Ethima organization.
131 lines (120 loc) • 4.26 kB
JavaScript
import spawn from "nano-spawn";
import { accessSync } from "node:fs";
import { env } from "node:process";
import { BranchesConfiguration } from "./branches.js";
import { CONFIGURATION } from "./configuration.js";
import { VersionedTemplatesConfiguration } from "./versioned-templates.js";
const GIT_ASSETS = [
CONFIGURATION.changelog_filename,
...CONFIGURATION.files_with_versioned_templates,
];
/**
* Checks whether a file is being tracked by Git.
*
* @param {string} path The path to the file to verify for whether it's being
* tracked by Git.
*
* @return bool Whether the file is being tracked by Git.
*/
async function isFileTrackedByGit(path) {
const { stdout } = await spawn("git", ["ls-files", path]);
return stdout.includes(path);
}
/*
* Determines whether the provided plugin should be added to the semantic
* release configuration based on the presence of select environment variables.
*
* @param {string} environment_variable The environment variable to verify the
* existence of (and equality to `"true"`) to include the specified `plugin`.
* @param {string} plugin The name of the NPM package providing the plugin.
*
* @return {Array} References the plugin if the `environment_variable` was set
* to `"true"` and is empty otherwise.
*/
function platformSpecificReleasePlugin(environment_variable, plugin) {
return env[environment_variable] === "true" ? [plugin] : [];
}
// Ensure the NPM plugin gets added to the semantic release pipeline if a
// `package.json` file is detected
const NPM_PLUGIN = [];
try {
accessSync("package.json");
GIT_ASSETS.push("package.json");
NPM_PLUGIN.push("@semantic-release/npm");
if (isFileTrackedByGit("package-lock.json")) {
GIT_ASSETS.push("package-lock.json");
}
} catch {}
const JULIA_PROJECT_TOML_PLUGIN = [];
try {
accessSync("Project.toml");
GIT_ASSETS.push("Project.toml");
JULIA_PROJECT_TOML_PLUGIN.push([
"semantic-release-replace-plugin",
{
replacements: [
{
files: "Project.toml",
// Only a single `version` field should be present in the
// `Project.toml`. However, due to the behavior of the `String.match`
// function used under the hood by the `replace-in-file` plugin to
// count the number of matches and replacements, it is necessary to
// set the `g` modifier on the regular expression to only count the
// actual number of matches instead of the first match and any
// capturing groups.
//
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#return_value
from: /version\s*=\s*"\d+(\.\d+){2}"/g,
to: 'version = "${nextRelease.version}"',
results: [
{
file: "Project.toml",
hasChanged: true,
numMatches: 1,
numReplacements: 1,
},
],
countMatches: true,
},
],
},
]);
} catch {}
// Determine the current branch based off well-known environment variables
// typically available in CI, i.e. Ethima specific configuration, GitLab CI,
// and GitHub Actions
const current_branch =
env.CURRENT_BRANCH ?? env.CI_COMMIT_REF_NAME ?? env.GITHUB_REF_NAME;
const SEMANTIC_RELEASE_CONFIGURATION = {
branches: BranchesConfiguration(current_branch, CONFIGURATION),
plugins: [
["@semantic-release/commit-analyzer", { preset: "conventionalcommits" }],
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
changelogFile: CONFIGURATION.changelog_filename,
changelogTitle: "# Changelog",
},
],
VersionedTemplatesConfiguration(
CONFIGURATION.files_with_versioned_templates,
),
...NPM_PLUGIN,
...JULIA_PROJECT_TOML_PLUGIN,
[
"@semantic-release/git",
{
assets: GIT_ASSETS,
message:
"build(release): ${nextRelease.version}\n\n${nextRelease.notes}",
},
],
...platformSpecificReleasePlugin(
"GITHUB_ACTIONS",
"@semantic-release/github",
),
...platformSpecificReleasePlugin("GITLAB_CI", "@semantic-release/gitlab"),
],
};
export default SEMANTIC_RELEASE_CONFIGURATION;