mirror of
https://github.com/yaklang/yaklang-chrome-extension.git
synced 2026-09-22 03:10:43 +08:00
fix(ci): make release zips reproducible and bump version to 0.2.1
adm-zip stamps entries with file mtimes, i.e. the git checkout time on CI, so two builds of the same commit differed byte-wise and tripped the immutable no-overwrite guard on workflow re-runs. Pin every entry to the commit date (SOURCE_DATE_EPOCH convention) instead. 0.2.0 was never published (no manifest entry, no GitHub release), but a stale chrome-store zip from the first failed run occupies its immutable slot; move the release to 0.2.1 rather than deleting the object.
This commit is contained in:
@@ -67,12 +67,21 @@ const pkg = JSON.parse(await readFile(resolve(root, 'package.json'), 'utf8'));
|
||||
const { version } = pkg;
|
||||
|
||||
let commit = null;
|
||||
let commitTime = null;
|
||||
try {
|
||||
const { stdout } = await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: root });
|
||||
commit = stdout.trim();
|
||||
const { stdout: iso } = await execFileAsync('git', ['show', '-s', '--format=%cI', 'HEAD'], { cwd: root });
|
||||
commitTime = new Date(iso.trim());
|
||||
} catch {
|
||||
// Not fatal: local runs outside a git worktree still package fine.
|
||||
}
|
||||
// adm-zip stamps every entry with the file mtime, which is the checkout time
|
||||
// on CI — two builds of the same commit would differ byte-wise and trip the
|
||||
// immutable no-overwrite guard on re-runs. Pin all entries to the commit
|
||||
// date (SOURCE_DATE_EPOCH convention) so artifacts are reproducible.
|
||||
const sourceDateEpoch = Number(process.env.SOURCE_DATE_EPOCH)
|
||||
|| (commitTime && !Number.isNaN(commitTime.getTime()) ? commitTime.getTime() : 0);
|
||||
|
||||
const versionDir = resolve(distDir, version);
|
||||
await mkdir(versionDir, { recursive: true });
|
||||
@@ -94,6 +103,8 @@ for (const target of VARIANTS) {
|
||||
// zip root, which is what browsers expect from a sideloaded extension.
|
||||
const zip = new AdmZip();
|
||||
zip.addLocalFolder(outputDir);
|
||||
const pinned = new Date(Math.floor(sourceDateEpoch / 2000) * 2000); // DOS time has 2s granularity
|
||||
for (const entry of zip.getEntries()) entry.header.time = pinned;
|
||||
await zip.writeZipPromise(zipPath);
|
||||
const sha256 = await sha256File(zipPath);
|
||||
const size = (await stat(zipPath)).size;
|
||||
|
||||
Reference in New Issue
Block a user