-
Notifications
You must be signed in to change notification settings - Fork 201
/
index.ts
152 lines (122 loc) · 4.06 KB
/
index.ts
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import {
Auto,
IPlugin,
execPromise,
validatePluginConfiguration,
SEMVER,
} from "@auto-it/core";
import { execSync } from "child_process";
import * as t from "io-ts";
import endent from "endent";
const required = t.interface({
/** The directory to push to gh-pages */
dir: t.string,
});
const optional = t.partial({
/** A command to build the documentation website */
buildCommand: t.string,
/** The branch to push to */
branch: t.string,
/** A label to look for and always publish the docs */
label: t.string,
});
const pluginOptions = t.intersection([required, optional]);
export type IGhPagesPluginOptions = t.TypeOf<typeof pluginOptions>;
const defaults = {
branch: "gh-pages",
label: "documentation",
};
/** Automate publishing to your gh-pages documentation website. */
export default class GhPagesPlugin implements IPlugin {
/** The name of the plugin */
name = "gh-pages";
/** The options of the plugin */
readonly options: IGhPagesPluginOptions & typeof defaults;
/** Initialize the plugin with it's options */
constructor(options: IGhPagesPluginOptions) {
this.options = { ...defaults, ...options };
}
/** Tap into auto plugin points. */
apply(auto: Auto) {
auto.hooks.validateConfig.tapPromise(this.name, async (name, options) => {
if (name === this.name || name === `@auto-it/${this.name}`) {
return validatePluginConfiguration(this.name, pluginOptions, options);
}
});
auto.hooks.beforeShipIt.tapPromise(
this.name,
async ({ releaseType, dryRun }) => {
if (releaseType !== "latest" || !auto.git || dryRun) {
return;
}
const bump = await auto.getVersion();
// If it's a bump the 'afterRelease' hook will release the docs
if (bump !== SEMVER.noVersion) {
return;
}
const sha = await auto.git.getSha();
const pr = await auto.git.matchCommitToPr(sha);
if (!pr) {
return;
}
const hasDocumentationLabel = pr.labels.includes(this.options.label);
if (!hasDocumentationLabel) {
return;
}
// If: skip-release + w/documentation label then we will push to gh-pages
await auto.setGitUser();
await this.releaseGhPages(auto);
}
);
auto.hooks.afterRelease.tapPromise(this.name, async ({ response }) => {
if (!response) {
return;
}
const releases = Array.isArray(response) ? response : [response];
const isPrerelease = releases.some((release) => release.data.prerelease);
if (isPrerelease) {
return;
}
await this.releaseGhPages(auto);
});
}
/** Release to gh-pages */
private async releaseGhPages(auto: Auto) {
if (this.options.buildCommand) {
execSync(this.options.buildCommand);
}
try {
const isVerbose =
auto.logger.logLevel === "verbose" ||
auto.logger.logLevel === "veryVerbose";
await execPromise("npx", [
"push-dir",
"--cleanup",
isVerbose && "--verbose",
`--remote=${auto.remote}`,
`--dir=${this.options.dir}`,
`--branch=${this.options.branch}`,
'--message="Update docs [skip ci]"',
]);
} catch (error) {
auto.logger.log.error(
"Oh no! It looks like there was trouble publishing to GitHub Pages 😢"
);
if (error.message.includes("git not clean")) {
auto.logger.log.error(endent`
Your repo currently has uncommitted files in it.
For the gh-pages plugin to work your git state must be clean.
You can do one of two things to fix this:
1. Add the files to your gitignore (ex: your built gh-pages website dist files)
2. Commit the files (ex: Something you want to track in the repo)
`);
const status = await execPromise("git", ["status", "--porcelain"]);
if (status) {
auto.logger.log.error("Uncomitted Changes:\n", status);
}
}
throw error;
}
auto.logger.log.success("Successfully deployed to GitHub Pages!");
}
}