Skip to content

Commit dea6634

Browse files
author
iexitdev
committed
ci(release): clean prerelease latest dist-tags
1 parent 18d6b0d commit dea6634

3 files changed

Lines changed: 66 additions & 1 deletion

File tree

.github/workflows/publish.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,34 @@ jobs:
154154
NPM_TAG: ${{ steps.package.outputs.npm_tag }}
155155
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
156156

157+
- name: Remove prerelease latest dist-tags
158+
run: |
159+
if [ "${NPM_TAG}" = "latest" ] || [[ "${PACKAGE_VERSION}" != *-* ]]; then
160+
echo "No prerelease latest tag cleanup needed."
161+
exit 0
162+
fi
163+
164+
for PACKAGE_DIR in $(node scripts/list-release-packages.mjs --publishable); do
165+
PACKAGE_JSON="${PACKAGE_DIR}/package.json"
166+
if [ "${PACKAGE_DIR}" = "." ]; then
167+
PACKAGE_JSON="package.json"
168+
fi
169+
170+
WORKSPACE_NAME=$(node -p "require('./${PACKAGE_JSON}').name")
171+
CURRENT_LATEST=$(npm dist-tag ls "${WORKSPACE_NAME}" | awk '/^latest:/ {print $2}')
172+
173+
if [ "${CURRENT_LATEST}" = "${PACKAGE_VERSION}" ]; then
174+
echo "Removing unintended latest tag from ${WORKSPACE_NAME}@${PACKAGE_VERSION}"
175+
npm dist-tag rm "${WORKSPACE_NAME}" latest
176+
else
177+
echo "Leaving ${WORKSPACE_NAME} latest tag unchanged (${CURRENT_LATEST:-missing})."
178+
fi
179+
done
180+
env:
181+
NPM_TAG: ${{ steps.package.outputs.npm_tag }}
182+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
183+
PACKAGE_VERSION: ${{ steps.package.outputs.version }}
184+
157185
- name: Verify npm registry publish state
158186
run: npm run release:publish:status -- --strict
159187

scripts/check-npm-publish-state.mjs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ export const buildNpmPublishState = async ({
7070
await npmView({ name: packageInfo.name, version })
7171
);
7272
const taggedVersion = viewResult.distTags[distTag];
73+
const latestVersion = viewResult.distTags.latest;
74+
const hasUnexpectedLatestTag =
75+
packageInfo.publishInBeta &&
76+
distTag !== "latest" &&
77+
version.includes("-") &&
78+
latestVersion === version;
7379

7480
let status = "pass";
7581
const expected = packageInfo.publishInBeta
@@ -80,6 +86,8 @@ export const buildNpmPublishState = async ({
8086
status = "missing";
8187
} else if (packageInfo.publishInBeta && taggedVersion !== version) {
8288
status = "wrong-dist-tag";
89+
} else if (hasUnexpectedLatestTag) {
90+
status = "unexpected-latest-tag";
8391
} else if (!packageInfo.publishInBeta && viewResult.published) {
8492
status = "unexpected-published";
8593
}
@@ -92,6 +100,7 @@ export const buildNpmPublishState = async ({
92100
published: viewResult.published,
93101
status,
94102
taggedVersion,
103+
latestVersion,
95104
version,
96105
visibleVersion: viewResult.version
97106
});
@@ -125,9 +134,12 @@ const formatState = (state) => {
125134
const tagText = entry.taggedVersion
126135
? `${entry.distTag}=${entry.taggedVersion}`
127136
: `${entry.distTag}=<missing>`;
137+
const latestText = entry.latestVersion
138+
? `, latest=${entry.latestVersion}`
139+
: "";
128140
const publishedText = entry.published ? "published" : "not published";
129141

130-
return `- ${entry.name}@${entry.version}: ${entry.status} (${publishedText}, ${tagText}; expected ${entry.expected})`;
142+
return `- ${entry.name}@${entry.version}: ${entry.status} (${publishedText}, ${tagText}${latestText}; expected ${entry.expected})`;
131143
});
132144

133145
return [

scripts/check-npm-publish-state.test.mjs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,29 @@ describe("npm publish state checker", () => {
104104
["@chart-kit/pro", "unexpected-published"]
105105
]);
106106
});
107+
108+
it("fails when a prerelease package is accidentally tagged latest", async () => {
109+
const state = await buildNpmPublishState({
110+
distTag: "next",
111+
manifest,
112+
npmView: createNpmView({
113+
"@chart-kit/core": {
114+
distTags: { latest: "7.0.0-next.0", next: "7.0.0-next.0" }
115+
},
116+
"@chart-kit/react-native": {},
117+
"react-native-chart-kit": {
118+
distTags: { latest: "6.12.2", next: "7.0.0-next.0" }
119+
}
120+
}),
121+
version: "7.0.0-next.0"
122+
});
123+
124+
expect(state.status).toBe("failed");
125+
expect(state.entries.map((entry) => [entry.name, entry.status])).toEqual([
126+
["@chart-kit/core", "unexpected-latest-tag"],
127+
["@chart-kit/react-native", "pass"],
128+
["react-native-chart-kit", "pass"],
129+
["@chart-kit/pro", "pass"]
130+
]);
131+
});
107132
});

0 commit comments

Comments
 (0)