-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathstate.js
More file actions
119 lines (97 loc) · 3.89 KB
/
state.js
File metadata and controls
119 lines (97 loc) · 3.89 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
const { readPreState } = require('@changesets/pre');
const { default: readChangesets } = require('@changesets/read');
const { join } = require('path');
const { fetch } = require('undici');
const { version, name: packageName } = require(join(__dirname, '../package.json'));
module.exports = async ({ github, context, core }) => {
const state = await getState({ github, context, core });
function setOutput(key, value) {
core.info(`State ${key} = ${value}`);
core.setOutput(key, value);
}
// Jobs to trigger
setOutput('start', shouldRunStart(state));
setOutput('promote', shouldRunPromote(state));
setOutput('changesets', shouldRunChangesets(state));
setOutput('publish', shouldRunPublish(state));
setOutput('merge', shouldRunMerge(state));
// Global Variables
setOutput('is_prerelease', state.prerelease);
};
// Checks if the package has already been published on npm
async function isPublishedOnNpm(packageName, version) {
const res = await fetch(`https://registry.npmjs.com/${packageName}/${version}`);
return res.ok;
}
// Determines if the 'start' job should run
function shouldRunStart({ isMain, isWorkflowDispatch, botRun }) {
return isMain && isWorkflowDispatch && !botRun;
}
// Determines if the 'promote' job should run
function shouldRunPromote({ isReleaseBranch, isWorkflowDispatch, botRun }) {
return isReleaseBranch && isWorkflowDispatch && !botRun;
}
// Determines if the 'changesets' job should run
function shouldRunChangesets({ isReleaseBranch, isPush, isWorkflowDispatch, botRun }) {
return (isReleaseBranch && isPush) || (isReleaseBranch && isWorkflowDispatch && botRun);
}
// Determines if the 'publish' job should run
function shouldRunPublish({ isReleaseBranch, isPush, hasPendingChangesets, isPublishedOnNpm, prerelease }) {
return isReleaseBranch && isPush && !hasPendingChangesets && !isPublishedOnNpm && !prerelease;
}
// Determines if the 'merge' job should run
function shouldRunMerge({
isReleaseBranch,
isPush,
prerelease,
isCurrentFinalVersion,
hasPendingChangesets,
prBackExists,
}) {
return isReleaseBranch && isPush && !prerelease && isCurrentFinalVersion && !hasPendingChangesets && !prBackExists;
}
// Gets the state of the repository, including various conditions like release status, branch, etc.
async function getState({ github, context, core }) {
// Variables not in the context
const refName = process.env.GITHUB_REF_NAME;
const botRun = process.env.TRIGGERING_ACTOR === 'github-actions[bot]';
const { changesets, preState } = await readChangesetState();
// Static vars
const state = {
refName,
hasPendingChangesets: changesets.length > 0,
prerelease: preState?.mode === 'pre',
isMain: refName === 'main',
isReleaseBranch: refName.startsWith('release-v'),
isWorkflowDispatch: context.eventName === 'workflow_dispatch',
isPush: context.eventName === 'push',
isCurrentFinalVersion: !version.includes('-rc.'),
botRun,
};
// Async vars
const { data: prs } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
head: `${context.repo.owner}:merge/${state.refName}`,
base: 'main',
state: 'open',
});
state.prBackExists = prs.length !== 0;
state.isPublishedOnNpm = await isPublishedOnNpm(packageName, version);
// Log every state value in debug mode
if (core.isDebug()) for (const [key, value] of Object.entries(state)) core.debug(`${key}: ${value}`);
return state;
}
// From https://github.com/changesets/action/blob/v1.4.1/src/readChangesetState.ts
async function readChangesetState(cwd = process.cwd()) {
const preState = await readPreState(cwd);
const isInPreMode = preState !== undefined && preState.mode === 'pre';
let changesets = await readChangesets(cwd);
if (isInPreMode) {
changesets = changesets.filter((x) => !preState.changesets.includes(x.id));
}
return {
preState: isInPreMode ? preState : undefined,
changesets,
};
}