Skip to content

Commit 3f288e8

Browse files
authored
ci: Skip over skipping release for manual stable release (#1843)
Annoyingly, releasing was skipped because we didn't run the release from a release commit https://github.com/braintrustdata/braintrust-sdk-javascript/actions/runs/24517456190/job/71665450112#step:7:11
1 parent e8e0bce commit 3f288e8

3 files changed

Lines changed: 38 additions & 12 deletions

File tree

.github/workflows/publish-js-sdk.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ jobs:
211211
id: detect
212212
env:
213213
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
214-
run: node scripts/release/should-publish-stable.mjs --output .release-manifest.json
214+
run: node scripts/release/should-publish-stable.mjs --allow-non-release-head --output .release-manifest.json
215215
- name: Configure git user
216216
run: |
217217
git config user.name "github-actions[bot]"

scripts/release/push-release-tags.mjs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ import { appendSummary, parseArgs } from "./_shared.mjs";
66
const args = parseArgs();
77
const manifestPath = args.manifest ?? ".release-manifest.json";
88
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
9+
const targetCommit = manifest.commit;
910

1011
if ((manifest.packages ?? []).length === 0) {
1112
console.log("No release tags to push.");
1213
process.exit(0);
1314
}
1415

16+
if (!targetCommit) {
17+
throw new Error("Release manifest is missing commit.");
18+
}
19+
1520
const tags = manifest.packages.map(
1621
(pkg) => pkg.tag ?? `${pkg.name}@${pkg.version}`,
1722
);
@@ -28,13 +33,17 @@ for (const tag of tags) {
2833

2934
if (!localTagExists(tag)) {
3035
toCreate.push(tag);
36+
} else if (getLocalTagTarget(tag) !== targetCommit) {
37+
throw new Error(
38+
`Local tag ${tag} already exists on ${getLocalTagTarget(tag)}, expected ${targetCommit}.`,
39+
);
3140
}
3241

3342
toPush.push(tag);
3443
}
3544

3645
for (const tag of toCreate) {
37-
execFileSync("git", ["tag", tag], { stdio: "inherit" });
46+
execFileSync("git", ["tag", tag, targetCommit], { stdio: "inherit" });
3847
}
3948

4049
if (toPush.length > 0) {
@@ -65,6 +74,12 @@ function localTagExists(tag) {
6574
);
6675
}
6776

77+
function getLocalTagTarget(tag) {
78+
return execFileSync("git", ["rev-list", "-n", "1", tag], {
79+
encoding: "utf8",
80+
}).trim();
81+
}
82+
6883
function fetchRemoteTags(tagsToCheck) {
6984
const result = spawnSync(
7085
"git",

scripts/release/should-publish-stable.mjs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414

1515
const args = parseArgs();
1616
const outputPath = args.output ?? ".release-manifest.json";
17+
const allowNonReleaseHead = args["allow-non-release-head"] === true;
1718
const packages = PUBLISHABLE_PACKAGES.map((approved) => {
1819
const manifest = readPackage(approved.dir);
1920
const publishedToNpm = isPublishedToNpm(manifest.name, manifest.version);
@@ -31,19 +32,17 @@ const packages = PUBLISHABLE_PACKAGES.map((approved) => {
3132
});
3233

3334
const actionablePackages = packages.filter((pkg) => pkg.needsPublish);
34-
const commit = execFileSync("git", ["rev-parse", "HEAD"], {
35+
const headCommit = execFileSync("git", ["rev-parse", "HEAD"], {
3536
encoding: "utf8",
3637
}).trim();
37-
const commitMessage = execFileSync("git", ["log", "-1", "--pretty=%B"], {
38-
encoding: "utf8",
39-
}).trim();
40-
const isReleaseCommit = /\[ci\] release/i.test(commitMessage);
41-
const hasWork = actionablePackages.length > 0 && isReleaseCommit;
38+
const headIsReleaseCommit = isReleaseCommit(headCommit);
39+
const hasWork =
40+
actionablePackages.length > 0 && (headIsReleaseCommit || allowNonReleaseHead);
4241
const releasePackages = hasWork ? actionablePackages : [];
4342

4443
const manifest = {
4544
mode: "stable",
46-
commit,
45+
commit: headCommit,
4746
packages: releasePackages,
4847
};
4948

@@ -63,9 +62,10 @@ writeGithubOutput("package_count", releasePackages.length);
6362
writeGithubOutput("manifest_path", outputPath);
6463

6564
if (!hasWork) {
66-
const message = actionablePackages.length
67-
? "Unpublished package versions exist, but HEAD is not a merged Changesets release commit, so stable publish is skipped."
68-
: "No stable publish work is required on this main commit.";
65+
const message =
66+
actionablePackages.length === 0
67+
? "No stable publish work is required on this main commit."
68+
: "Unpublished package versions exist, but HEAD is not a merged Changesets release commit, so stable publish is skipped.";
6969
console.log(message);
7070
appendSummary(`## Stable publish\n\n${message}`);
7171
process.exit(0);
@@ -96,3 +96,14 @@ function isPublishedToNpm(name, version) {
9696

9797
return result.stdout.trim() === version;
9898
}
99+
100+
function isReleaseCommit(commit) {
101+
const commitMessage = execFileSync(
102+
"git",
103+
["log", "-1", "--pretty=%B", commit],
104+
{
105+
encoding: "utf8",
106+
},
107+
).trim();
108+
return /\[ci\] release/i.test(commitMessage);
109+
}

0 commit comments

Comments
 (0)