Skip to content

Commit

Permalink
feat: add workflow check
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCalzone committed Jul 1, 2021
1 parent fb26b06 commit bf75c2c
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
Placeholder for the next version (at the beginning of the line):
## **WORK IN PROGRESS**
-->
## **WORK IN PROGRESS**
* Added an automated check of the Github Actions workflow file to spot potential errors that could fail a release

## 2.1.0 (2021-06-30)
* Add support to release `yarn v2+` workspaces (when the `workspace-tools` and `version` plugins are installed)

Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ for example.

Once you are ready to release the changes, commit everything so the working tree is clean. Also make sure that you are on the `master` branch. Now you can create a release by executing:
```
npm run release [<releaseType> [<postfix>]] [-- [--dry] [--all]]
npm run release [<releaseType> [<postfix>]] [-- [--dry] [--all] [--no-workflow-check]]
```
You can choose between the following release types:
The available release types are:
Expand Down Expand Up @@ -111,6 +111,15 @@ Although the release commit should only include the changes relevant to the vers
npm run release patch -- --all
```

### Skip the release workflow check
The release script tries to find common errors in the Github Actions release workflow file. If the check results in a false positive, you can disable this check with the `--no-workflow-check` option.

```bash
npm run release patch -- --no-workflow-check
```

This can also be configured with `noWorkflowCheck: true` in the config file.

### Using a different remote than `origin`
If the remote you want to push to is not called `origin`, you can use the `r` flag to specify a different one (after the double dashes!)
Make sure to use the complete remote branch name:
Expand Down
5 changes: 4 additions & 1 deletion build/parseArgs.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const yarn_1 = require("./yarn");
async function parseArgs() {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
// Try to read the CLI args from an RC file
let rcFile;
const argv = yargs_1.default.parseSync();
Expand Down Expand Up @@ -61,6 +61,8 @@ async function parseArgs() {
// in lerna mode, these have no effect
const isDryRun = (_g = argv.dry) !== null && _g !== void 0 ? _g : argv._.includes("--dry");
const allChanges = (_j = (_h = rcFile === null || rcFile === void 0 ? void 0 : rcFile.all) !== null && _h !== void 0 ? _h : argv.all) !== null && _j !== void 0 ? _j : argv._.includes("--all");
// Don't check workflow file
const noWorkflowCheck = (_l = (_k = rcFile === null || rcFile === void 0 ? void 0 : rcFile.noWorkflowCheck) !== null && _k !== void 0 ? _k : argv.noWorkflowCheck) !== null && _l !== void 0 ? _l : argv._.includes("--no-workflow-check");
return {
lernaCheck,
lerna,
Expand All @@ -69,6 +71,7 @@ async function parseArgs() {
allChanges,
scripts,
remote,
noWorkflowCheck,
};
}
exports.parseArgs = parseArgs;
29 changes: 28 additions & 1 deletion build/release.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const yarn_1 = require("./yarn");
var _a, _b;
const rootDir = process.cwd();
const argv = yargs_1.default.parseSync();
const { allChanges, isDryRun, yarnWorkspace, lerna, lernaCheck, scripts: userScripts, remote, } = await parseArgs_1.parseArgs();
const { allChanges, isDryRun, yarnWorkspace, lerna, lernaCheck, scripts: userScripts, remote, noWorkflowCheck, } = await parseArgs_1.parseArgs();
function fail(reason) {
console.error("");
console.error(safe_1.default.red("ERROR: " + reason));
Expand All @@ -84,6 +84,33 @@ const yarn_1 = require("./yarn");
fail("Missing property version from lerna.json!");
}
}
// ensure that the release workflow does not check for base_ref
// This is pretty specific to ioBroker's release workflow, but better than silently failing
const workflowPath = path.join(rootDir, ".github/workflows/test-and-release.yml");
if (!noWorkflowCheck && fs.existsSync(workflowPath)) {
let content = fs.readFileSync(workflowPath, "utf8");
// Find deploy step, crudely by string manipulation. TODO: This should be done with a yaml parser
while (true) {
let match = /^[ \t]+deploy:/gm.exec(content);
if (!match)
break;
content = content.substr(match.index);
match = /^[ \t]+if: |/gm.exec(content);
if (!match)
break;
content = content.substr(match.index);
match = /^[ \t]+github\.event\.base_ref ==/gm.exec(content);
if (!match)
break;
let line = content.substr(match.index);
line = line.substr(0, line.indexOf("\n"));
fail(`The ${safe_1.default.bold("deploy")} job in ${safe_1.default.bold(`.github/workflows/test-and-release.yml`)} potentially has an error, which can cause your deploy to fail.
Remove this line to fix it:
${safe_1.default.inverse(line)}
You can suppress this check with the ${safe_1.default.bold("--no-workflow-check")} flag.`);
}
}
// If this is an ioBroker project, also bump the io-package.json
const ioPackPath = path.join(rootDir, "io-package.json");
const hasIoPack = fs.existsSync(ioPackPath);
Expand Down
4 changes: 4 additions & 0 deletions src/parseArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export async function parseArgs() {
const allChanges: boolean =
rcFile?.all ?? argv.all ?? argv._.includes("--all");

// Don't check workflow file
const noWorkflowCheck: boolean = rcFile?.noWorkflowCheck ?? argv.noWorkflowCheck ?? argv._.includes("--no-workflow-check");

return {
lernaCheck,
lerna,
Expand All @@ -53,5 +56,6 @@ export async function parseArgs() {
allChanges,
scripts,
remote,
noWorkflowCheck,
};
}
35 changes: 35 additions & 0 deletions src/release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { getChangedWorkspaces } from "./yarn";
lernaCheck,
scripts: userScripts,
remote,
noWorkflowCheck,
} = await parseArgs();

function fail(reason: string): never {
Expand Down Expand Up @@ -81,6 +82,40 @@ import { getChangedWorkspaces } from "./yarn";
}
}

// ensure that the release workflow does not check for base_ref
// This is pretty specific to ioBroker's release workflow, but better than silently failing
const workflowPath = path.join(
rootDir,
".github/workflows/test-and-release.yml",
);
if (!noWorkflowCheck && fs.existsSync(workflowPath)) {
let content = fs.readFileSync(workflowPath, "utf8");
// Find deploy step, crudely by string manipulation. TODO: This should be done with a yaml parser
while (true) {
let match = /^[ \t]+deploy:/gm.exec(content);
if (!match) break;
content = content.substr(match.index);

match = /^[ \t]+if: |/gm.exec(content);
if (!match) break;
content = content.substr(match.index);

match = /^[ \t]+github\.event\.base_ref ==/gm.exec(content);
if (!match) break;

let line = content.substr(match.index);
line = line.substr(0, line.indexOf("\n"));

fail(`The ${colors.bold("deploy")} job in ${colors.bold(
`.github/workflows/test-and-release.yml`,
)} potentially has an error, which can cause your deploy to fail.
Remove this line to fix it:
${colors.inverse(line)}
You can suppress this check with the ${colors.bold("--no-workflow-check")} flag.`);
}
}

// If this is an ioBroker project, also bump the io-package.json
const ioPackPath = path.join(rootDir, "io-package.json");
const hasIoPack = fs.existsSync(ioPackPath);
Expand Down

0 comments on commit bf75c2c

Please sign in to comment.