-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
134 lines (104 loc) · 3.56 KB
/
index.js
File metadata and controls
134 lines (104 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
const fs = require("fs");
const path = require("path");
const jsYaml = require("js-yaml");
const walk = require("klaw-sync");
const assert = require("assert");
const pkgDir = require("pkg-dir");
const PACKAGE_DIR = pkgDir.sync();
const DOT_GITHUB_DIR = path.resolve(PACKAGE_DIR, ".github");
const DOT_GITHUB_WORKFLOWS_DIR = path.resolve(DOT_GITHUB_DIR, "workflows");
const README_CONTENTS = (workflowsDir) => `\
DO NOT USE THIS DIRECTORY!!!
Add/edit workflows in the ${workflowsDir} folder instead.
They are copied over to here using a pre-commit hook.\n`;
// The include directive regex.
// Match example: "#!include(my_partial)"
// Group captures for above example:
// - leading_whitespace: " "
// - partial_name: "my_partial"
const DIRECTIVE_RE =
// capture whitespace at the beginning of the line
// but ignore newlines and carriage returns
// |
// |
// |-------\
// v v
/^(?<leading_whitespace>[^\S\r\n]*)#!\s*include\((?<partial_name>[a-zA-Z0-9._-]+)\)/gm;
const DEFAULT_OPTIONS = {
partialsDir: "github/partials",
workflowsDir: "github/workflows",
includeWarningReadme: true,
};
function debug(...args) {
if (process.env.DEBUG) {
console.log(...args);
}
}
// Compress used loosely here. Sadly GH doesn't support highly compressed YAML
// so the best we can do is just remove all whitespace and comments from the output.
function compressYaml(yamlStr) {
const yml = jsYaml.load(yamlStr);
return jsYaml.dump(yml, {
lineWidth: -1, // do not impose line width restriction
});
}
function create(options) {
const { partialsDir, workflowsDir, includeWarningReadme } = {
...DEFAULT_OPTIONS,
...options,
};
assert(
path.relative(PACKAGE_DIR, workflowsDir) !==
path.relative(PACKAGE_DIR, ".github/workflows"),
"workflowsDir must not be .github/workflows"
);
const interpolate = (contents) => {
return contents.replace(DIRECTIVE_RE, (...args) => {
const groups = args.pop();
const partialName = groups.partial_name;
debug("- including partial:", partialName);
let partialPath = path.resolve(partialsDir, partialName);
if (!/\.[a-z]$/i.test(partialPath)) {
partialPath += ".yml";
}
if (!fs.existsSync(partialPath)) {
throw new Error(`partial "${partialName}" does not exist`);
}
const partialContents = interpolate(
fs.readFileSync(partialPath).toString()
);
return partialContents.replace(/^/gm, groups.leading_whitespace);
});
};
console.group("Running github-actions-include...");
fs.rmdirSync(DOT_GITHUB_WORKFLOWS_DIR, {
recursive: true,
});
fs.mkdirSync(DOT_GITHUB_WORKFLOWS_DIR);
if (includeWarningReadme) {
// Reinstate the warning README.md under .github/workflows
fs.writeFileSync(
path.resolve(DOT_GITHUB_DIR, "workflows/README.md"),
README_CONTENTS(workflowsDir)
);
}
walk(workflowsDir, {
nodir: true,
traverseAll: true,
filter: (item) => item.path.endsWith(".yml"),
}).forEach(({ path: filepath }) => {
let contents = fs.readFileSync(filepath).toString();
console.group("Processing:", path.relative(workflowsDir, filepath));
if (DIRECTIVE_RE.test(contents)) {
contents = interpolate(contents);
}
fs.writeFileSync(
path.resolve(DOT_GITHUB_WORKFLOWS_DIR, path.basename(filepath)),
compressYaml(contents)
);
console.groupEnd();
});
console.log("Done");
console.groupEnd();
}
module.exports = create;