hermes-agent/apps/desktop/scripts/write-build-stamp.test.mjs
Austin Pickett bc6839aa37
fix(desktop): stop hard-failing pack on non-git checkouts + fix ZIP-path autocrlf (supersedes #67643) (#67730)
* fix(desktop): allow write-build-stamp from non-git checkouts

Stop hard-failing npm pack when neither GITHUB_SHA nor git HEAD is
available (ZIP installs / broken .git). Emit an explicit fallback stamp
instead so local Windows desktop builds can finish (#50823).

* fix(desktop): treat fallback stamps as unpinned; harden Windows install

Keep all-zero fallback commits out of -Commit/--commit pins and fetch
install.ps1 by branch instead. After bootstrap, pin the marker to the
checkout HEAD so isBootstrapComplete accepts it. On Windows, force ZIP
checkout, seed GITHUB_SHA (ASCII-only install.ps1), and avoid the pack
stamp failure.

* fix(install): pin core.autocrlf=false before ZIP-path checkout (#50823 review)

The ZIP-fallback path added in #67643 runs `git checkout -f FETCH_HEAD`
before core.autocrlf gets pinned (which only happened later, on the
shared clone-path config). On Git for Windows -- where core.autocrlf
defaults to true -- that renormalizes the repo's LF text files to CRLF in
the working tree during checkout, leaving the freshly-created managed
checkout dirty versus HEAD and aborting the next `hermes update`. That is
the exact "dirty tree the user never touched" failure the surrounding
code already guards against (install.ps1:1461-1469, 1750-1753).

Move the `config core.autocrlf false` pin to run immediately after
`git init`, before the fetch/checkout. The later idempotent pin on the
shared clone path is retained so git-clone installs are unaffected.

Addresses teknium1's review on #67643 and supersedes it, preserving the
original author's two commits.

Co-authored-by: HexLab98 <8422520+HexLab98@users.noreply.github.com>

* chore(contributors): map austinpickett commit email for attribution

The check-attribution CI gate flagged austinpickett@users.noreply.github.com
as an unmapped commit-author email (introduced by the autocrlf fix commit
on this PR). Add the per-email mapping file as the gate instructs (the
legacy AUTHOR_MAP in scripts/release.py is frozen).

---------

Co-authored-by: HexLab98 <liruixinch@outlook.com>
Co-authored-by: austinpickett <austinpickett@users.noreply.github.com>
Co-authored-by: HexLab98 <8422520+HexLab98@users.noreply.github.com>
2026-07-19 19:29:36 -04:00

86 lines
2.4 KiB
JavaScript

import assert from 'node:assert/strict'
import { test } from 'vitest'
import {
FALLBACK_BRANCH,
FALLBACK_COMMIT,
fromCI,
fromFallback,
fromLocalGit,
isFallbackCommit,
resolveStamp
} from './write-build-stamp.mjs'
test('fromCI reads GITHUB_SHA / GITHUB_REF_NAME', () => {
assert.deepEqual(
fromCI({ GITHUB_SHA: 'a'.repeat(40), GITHUB_REF_NAME: 'release' }),
{ commit: 'a'.repeat(40), branch: 'release', dirty: false, source: 'ci' }
)
assert.equal(fromCI({}), null)
})
test('fromLocalGit returns null when git rev-parse fails', () => {
const stamp = fromLocalGit('/tmp/not-a-repo', () => null)
assert.equal(stamp, null)
})
test('fromLocalGit reads HEAD + branch + dirty status', () => {
const calls = []
const execFn = (cmd) => {
calls.push(cmd)
if (cmd === 'git rev-parse HEAD') return 'b'.repeat(40)
if (cmd === 'git rev-parse --abbrev-ref HEAD') return 'main'
if (cmd === 'git status --porcelain -uno') return ' M apps/desktop/package.json'
return null
}
assert.deepEqual(fromLocalGit('/repo', execFn), {
commit: 'b'.repeat(40),
branch: 'main',
dirty: true,
source: 'local'
})
assert.ok(calls.includes('git rev-parse HEAD'))
})
test('fromFallback uses the all-zero placeholder commit', () => {
assert.deepEqual(fromFallback(), {
commit: FALLBACK_COMMIT,
branch: FALLBACK_BRANCH,
dirty: false,
source: 'fallback'
})
assert.equal(isFallbackCommit(FALLBACK_COMMIT), true)
assert.equal(isFallbackCommit('a'.repeat(40)), false)
})
test('resolveStamp prefers CI over local git over fallback', () => {
const ci = resolveStamp({
env: { GITHUB_SHA: 'c'.repeat(40), GITHUB_REF_NAME: 'main' },
execFn: () => 'should-not-run'
})
assert.equal(ci.source, 'ci')
assert.equal(ci.commit, 'c'.repeat(40))
const local = resolveStamp({
env: {},
execFn: (cmd) => {
if (cmd === 'git rev-parse HEAD') return 'd'.repeat(40)
if (cmd === 'git rev-parse --abbrev-ref HEAD') return 'main'
if (cmd === 'git status --porcelain -uno') return ''
return null
}
})
assert.equal(local.source, 'local')
assert.equal(local.commit, 'd'.repeat(40))
assert.equal(local.dirty, false)
})
test('resolveStamp falls back when neither CI nor git is available', () => {
const stamp = resolveStamp({ env: {}, execFn: () => null })
assert.deepEqual(stamp, {
commit: FALLBACK_COMMIT,
branch: FALLBACK_BRANCH,
dirty: false,
source: 'fallback'
})
})