Repository navigation
Expand file tree
/
Copy pathcheck-plugin-release-metadata.yml
More file actions
124 lines (102 loc) · 4.63 KB
/
Copy pathcheck-plugin-release-metadata.yml
File metadata and controls
124 lines (102 loc) · 4.63 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
name: Check plugin release metadata
on:
pull_request:
branches:
- main
permissions:
contents: read
jobs:
metadata:
name: Version and release notes updated
runs-on: ubuntu-latest
steps:
- name: Check out pull request
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Compare plugin release metadata
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
node <<'NODE'
const fs = require('node:fs');
const { execFileSync } = require('node:child_process');
const semverPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
function parseVersion(value, source) {
if (typeof value !== 'string') {
throw new Error(`${source} plugin.json does not contain a string version.`);
}
const match = semverPattern.exec(value);
if (!match) {
throw new Error(`${source} plugin version ${JSON.stringify(value)} is not valid semantic versioning.`);
}
return {
value,
core: match.slice(1, 4).map(BigInt),
prerelease: match[4] ? match[4].split('.') : [],
};
}
function compareIdentifiers(left, right) {
const leftIsNumeric = /^\d+$/.test(left);
const rightIsNumeric = /^\d+$/.test(right);
if (leftIsNumeric && rightIsNumeric) {
return Number(BigInt(left) > BigInt(right)) - Number(BigInt(left) < BigInt(right));
}
if (leftIsNumeric !== rightIsNumeric) {
return leftIsNumeric ? -1 : 1;
}
return Number(left > right) - Number(left < right);
}
function compareVersions(left, right) {
for (let index = 0; index < left.core.length; index += 1) {
if (left.core[index] !== right.core[index]) {
return left.core[index] > right.core[index] ? 1 : -1;
}
}
if (left.prerelease.length === 0 || right.prerelease.length === 0) {
return Number(left.prerelease.length === 0) - Number(right.prerelease.length === 0);
}
const length = Math.max(left.prerelease.length, right.prerelease.length);
for (let index = 0; index < length; index += 1) {
if (left.prerelease[index] === undefined) return -1;
if (right.prerelease[index] === undefined) return 1;
const comparison = compareIdentifiers(left.prerelease[index], right.prerelease[index]);
if (comparison !== 0) return comparison;
}
return 0;
}
function getReleaseNotes(manifest) {
const value = manifest.extensions?.['com.openai']?.publication?.release_notes;
return typeof value === 'string' ? value.trim() : null;
}
try {
const baseManifest = JSON.parse(
execFileSync('git', ['show', `${process.env.BASE_SHA}:plugin.json`], { encoding: 'utf8' }),
);
const pullRequestManifest = JSON.parse(fs.readFileSync('plugin.json', 'utf8'));
const baseVersion = parseVersion(baseManifest.version, 'Base branch');
const pullRequestVersion = parseVersion(pullRequestManifest.version, 'Pull request');
const baseReleaseNotes = getReleaseNotes(baseManifest);
const pullRequestReleaseNotes = getReleaseNotes(pullRequestManifest);
if (compareVersions(pullRequestVersion, baseVersion) <= 0) {
throw new Error(
`plugin.json version must be greater than ${baseVersion.value}; found ${pullRequestVersion.value}.`,
);
}
if (!pullRequestReleaseNotes) {
throw new Error(
'plugin.json must contain non-empty extensions.com.openai.publication.release_notes.',
);
}
if (pullRequestReleaseNotes === baseReleaseNotes) {
throw new Error(
'extensions.com.openai.publication.release_notes must be updated for this release.',
);
}
console.log(`Plugin version incremented from ${baseVersion.value} to ${pullRequestVersion.value}.`);
console.log('Plugin release notes were updated.');
} catch (error) {
console.error(error instanceof Error ? error.message : error);
process.exit(1);
}
NODE