From 82b288dc3836b65dbb480529923ff8ca7ff69822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 4 Aug 2026 11:57:01 +0200 Subject: [PATCH] harden against tag<->commit mismatch --- src/github.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/github.ts b/src/github.ts index 1b8e47d..f19593c 100644 --- a/src/github.ts +++ b/src/github.ts @@ -1,3 +1,4 @@ +import assert from "node:assert/strict"; import { Buffer } from "node:buffer"; import * as core from "@actions/core"; import { exec, getExecOutput } from "@actions/exec"; @@ -225,6 +226,27 @@ export class GitHub { ); } + async #getRemoteTagCommit(tag: string) { + const { data: ref } = await this.octokit.rest.git.getRef({ + ...context.repo, + ref: `tags/${tag}`, + }); + let target: { type: string; sha: string } = ref.object; + while (target.type === "tag") { + const { data: tagObject } = await this.octokit.rest.git.getTag({ + ...context.repo, + tag_sha: target.sha, + }); + target = tagObject.object; + } + assert.equal( + target.type, + "commit", + `Tag ${tag} points to a ${target.type}, not a commit`, + ); + return target.sha; + } + async pushTag(tag: string, commit = context.sha) { if (!this.pushWithGitCli) { try { @@ -242,6 +264,12 @@ export class GitHub { }); } catch (err) { if (isAlreadyExistingRefError(err)) { + const remoteCommit = await this.#getRemoteTagCommit(tag); + assert.equal( + remoteCommit, + commit, + `Tag ${tag} points to commit ${remoteCommit}, expected ${commit}`, + ); // The tag was likely pushed by a custom publish script. core.info(`Tag ${tag} already exists`); return;