Skip to content

Commit

Permalink
refactor: split module for maintanability (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinDeJong-TomTom committed May 28, 2022
1 parent 5e589e3 commit d6bcf90
Show file tree
Hide file tree
Showing 5 changed files with 346 additions and 207 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Changed
- Improved user feedback during execution of the action

## [1.0.1] - 2022-05-18
### Fixed
- The requirements.txt file is now properly included in the npm package
Expand Down
221 changes: 153 additions & 68 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9958,7 +9958,7 @@ function wrappy (fn, cb) {

/***/ }),

/***/ 399:
/***/ 8604:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {

"use strict";
Expand All @@ -9978,29 +9978,6 @@ function wrappy (fn, cb) {
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
Expand All @@ -10011,11 +9988,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.is_commit_valid = exports.get_commits = void 0;
const core = __nccwpck_require__(2186);
const exec = __nccwpck_require__(1514);
const github = __nccwpck_require__(5438);
const fs = __nccwpck_require__(7147);
const path = __importStar(__nccwpck_require__(1017));
/**
* Strips ANSI color codes from the provided message
* @param message
Expand Down Expand Up @@ -10045,46 +10022,6 @@ function get_error_subjects(message) {
}
return errors;
}
/**
* Confirms whether Python >=3.8 and pip are present on the runner
*/
function check_prerequisites() {
return __awaiter(this, void 0, void 0, function* () {
const python_version_re = /Python\s*(\d+)\.(\d+)\.(\d+)/;
const { stdout: python_version } = yield exec.getExecOutput("python3", ["--version"], { silent: true });
const match = python_version_re.exec(python_version);
if (!match || match.length != 4) {
throw new Error("Unable to determine the installed Python version.");
}
if (!(parseInt(match[1]) == 3 && parseInt(match[2]) >= 8)) {
throw new Error(`Incorrect Python version installed; found ${match[1]}.${match[2]}.${match[3]}, expected >= 3.8.0`);
}
try {
const { stdout: pip_version } = yield exec.getExecOutput("python3", ["-m", "pip", "--version"], { silent: true });
}
catch (_a) {
throw new Error("Unable to determine the installed Pip version.");
}
});
}
/**
* Installs the latest version of commisery
*/
function prepare_environment() {
return __awaiter(this, void 0, void 0, function* () {
// Ensure Python (>= 3.8) and pip are installed
yield check_prerequisites();
// Install latest version of commisery
yield exec.exec("python3", [
"-m",
"pip",
"install",
"--upgrade",
"--requirement",
path.join(__dirname, "requirements.txt"),
]);
});
}
/**
* Retrieves a list of commits associated with the specified Pull Request
* @param owner GitHub owner
Expand All @@ -10105,6 +10042,7 @@ function get_commits(owner, repo, pullrequest_id) {
return commits;
});
}
exports.get_commits = get_commits;
/**
* Validates the commit object against the Conventional Commit convention
* @param commit
Expand All @@ -10130,17 +10068,161 @@ function is_commit_valid(commit) {
return [stderr == "", get_error_subjects(stderr)];
});
}
exports.is_commit_valid = is_commit_valid;


/***/ }),

/***/ 6869:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {

"use strict";

/**
* Copyright (C) 2020-2022, TomTom (http://tomtom.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.prepare_environment = void 0;
const exec = __nccwpck_require__(1514);
const path = __importStar(__nccwpck_require__(1017));
/**
* Checks whether the provided Python version is present
*
* @param major Major version
* @param minor Minor version
*/
function check_python_prerequisites(major, minor) {
return __awaiter(this, void 0, void 0, function* () {
const python_version_re = /Python\s*(\d+)\.(\d+)\.(\d+)/;
const { stdout: python_version } = yield exec.getExecOutput("python3", ["--version"], { silent: true });
const match = python_version_re.exec(python_version);
if (!match || match.length != 4) {
throw new Error("Unable to determine the installed Python version.");
}
if (!(parseInt(match[1]) == major && parseInt(match[2]) >= minor)) {
throw new Error(`Incorrect Python version installed; found ${match[1]}.${match[2]}.${match[3]}, expected >= ${major}.${minor}.0`);
}
try {
const { stdout: pip_version } = yield exec.getExecOutput("python3", ["-m", "pip", "--version"], { silent: true });
}
catch (_a) {
throw new Error("Unable to determine the installed Pip version.");
}
});
}
/**
* Prepares the environment for using commisery
*/
function prepare_environment() {
return __awaiter(this, void 0, void 0, function* () {
// Ensure Python (>= 3.8) and pip are installed
yield check_python_prerequisites(3, 8);
// Install latest version of commisery
yield exec.exec("python3", [
"-m",
"pip",
"install",
"--upgrade",
"--requirement",
path.join(__dirname, "requirements.txt"),
], { silent: true });
});
}
exports.prepare_environment = prepare_environment;


/***/ }),

/***/ 399:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {

"use strict";

/**
* Copyright (C) 2020-2022, TomTom (http://tomtom.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const core = __nccwpck_require__(2186);
const environment_1 = __nccwpck_require__(6869);
const commisery_1 = __nccwpck_require__(8604);
function run() {
return __awaiter(this, void 0, void 0, function* () {
// Ensure that commisery is installed
try {
yield prepare_environment();
console.log("🌲 Preparing environment...");
yield (0, environment_1.prepare_environment)();
let [owner, repo] = (process.env.GITHUB_REPOSITORY || "").split("/");
// Validate each commit against Conventional Commit standard
let commits = yield get_commits(owner, repo, core.getInput("pull_request"));
let commits = yield (0, commisery_1.get_commits)(owner, repo, core.getInput("pull_request"));
let success = true;
console.log("🚀 Validating your commit messages...");
for (const commit of commits) {
let [valid, errors] = yield is_commit_valid(commit);
let [valid, errors] = yield (0, commisery_1.is_commit_valid)(commit);
if (!valid) {
core.summary
.addHeading(commit.commit.message, 2)
Expand All @@ -10156,6 +10238,9 @@ function run() {
// Post summary
core.summary.write();
}
else {
console.log("✅ Your commit messages comply to the conventional commit standard!");
}
}
catch (ex) {
core.setFailed(ex.message);
Expand Down
104 changes: 104 additions & 0 deletions src/commisery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* Copyright (C) 2020-2022, TomTom (http://tomtom.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const core = require("@actions/core");
const exec = require("@actions/exec");
const github = require("@actions/github");
const fs = require("fs");

/**
* Strips ANSI color codes from the provided message
* @param message
* @returns message without ANSI color codes
*/
function strip_ansicolor(message: string) {
const pattern = [
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))",
].join("|");

return message.replace(new RegExp(pattern, "g"), "");
}

/**
* Converts error message into GitHub accepted format
* @param message
* @returns multiline message
*/
function get_error_subjects(message: string) {
let errors: string[] = [];

for (var line of strip_ansicolor(message).split("\n")) {
if (line.startsWith(".commit-message") && line.indexOf(": error:") > -1) {
errors.push(line);
} else if (line.length > 0) {
errors[errors.length - 1] += `\n${line}`;
}
}

return errors;
}

/**
* Retrieves a list of commits associated with the specified Pull Request
* @param owner GitHub owner
* @param repo GitHub repository
* @param pullrequest_id GitHub Pullrequest ID
* @returns List of commit objects
*/
export async function get_commits(
owner: string,
repo: string,
pullrequest_id: string
) {
const github_token = core.getInput("token");
const octokit = github.getOctokit(github_token);

// Retrieve commits from provided Pull Request
const { data: commits } = await octokit.rest.pulls.listCommits({
owner: owner,
repo: repo,
pull_number: pullrequest_id,
});

return commits;
}

/**
* Validates the commit object against the Conventional Commit convention
* @param commit
* @returns
*/
export async function is_commit_valid(commit): Promise<[boolean, string[]]> {
// Provide the commit message as file
await fs.writeFileSync(".commit-message", commit.commit.message);

let stderr = "";

try {
await exec.exec("commisery-verify-msg", [".commit-message"], {
ignoreReturnCode: true,
silent: true,
listeners: {
stderr: (data: Buffer): string => (stderr += data.toString()),
},
});
} catch (error) {
core.debug("Error detected while executing commisery");
}

return [stderr == "", get_error_subjects(stderr)];
}
Loading

0 comments on commit d6bcf90

Please sign in to comment.