fix(release): wall-entry commits under an explicit git identity
git commit in the cache clone relied on ambient user.name/user.email, which the box has neither globally nor per-repo — every push-side test failed there with "unable to auto-detect email address" while passing on a laptop with a global identity configured. Resolve the identity from the repository the rail is actually running in (process.cwd(), the developer's own checkout release.sh invokes this from) and pass it explicitly via -c user.name/-c user.email on the commit; refuse by name if neither is set. Give the test fixtures a repo-local identity the same way seedRemote already does for the seed clone, so the suite is deterministic on any host.
This commit is contained in:
parent
1882532cb7
commit
aac853d3e8
2 changed files with 44 additions and 1 deletions
|
|
@ -337,6 +337,36 @@ function git(args, cwd) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the git identity for the wall commit from the repository the rail
|
||||
* is actually running in — the developer's own checkout (`process.cwd()`;
|
||||
* `release.sh` invokes this script from the repo root with no `cd`), via
|
||||
* git's normal config precedence (repo-local, then global, then system).
|
||||
* Never guessed and never left to git's own "who are you?" prompt: a host
|
||||
* with no configured identity anywhere (a bare CI box, say) must refuse
|
||||
* loudly rather than have git manufacture a placeholder identity or hang.
|
||||
* @returns {{name: string, email: string}}
|
||||
*/
|
||||
function resolveWallCommitIdentity() {
|
||||
const repo = process.cwd()
|
||||
let name = ''
|
||||
let email = ''
|
||||
try {
|
||||
name = git(['config', 'user.name'], repo)
|
||||
} catch {
|
||||
name = ''
|
||||
}
|
||||
try {
|
||||
email = git(['config', 'user.email'], repo)
|
||||
} catch {
|
||||
email = ''
|
||||
}
|
||||
if (!name || !email) {
|
||||
fail('no git identity for the wall commit — set user.name/user.email')
|
||||
}
|
||||
return { name, email }
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a clean, up-to-date local clone of the releases repo at
|
||||
* `cacheDir`, checked out on `main` — cloning fresh if `cacheDir` has no
|
||||
|
|
@ -423,9 +453,14 @@ function publishEntry(entry, product, remote, cacheDir) {
|
|||
return
|
||||
}
|
||||
|
||||
const identity = resolveWallCommitIdentity()
|
||||
|
||||
try {
|
||||
git(['add', `${product}.json`], cacheDir)
|
||||
git(['commit', '-m', `chore(wall): ${product} ${entry.version}`], cacheDir)
|
||||
git(
|
||||
['-c', `user.name=${identity.name}`, '-c', `user.email=${identity.email}`, 'commit', '-m', `chore(wall): ${product} ${entry.version}`],
|
||||
cacheDir,
|
||||
)
|
||||
} catch (err) {
|
||||
fail(`cannot commit the wall entry in "${cacheDir}" — ${/** @type {Error} */ (err).message}\n cure: inspect "${cacheDir}" by hand and re-run once its git state is clean`)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,14 @@ let cacheDir: string
|
|||
|
||||
beforeEach(() => {
|
||||
dir = mkdtempSync(join(tmpdir(), 'wall-entry-test-'))
|
||||
// wall-entry.mjs is run with this dir as its cwd, standing in for the real
|
||||
// developer checkout it reads its commit identity from (process.cwd()) —
|
||||
// give it a repo-local identity the same way seedRemote gives one to the
|
||||
// seed clone, so the suite is deterministic on a host with no global git
|
||||
// config (a bare CI box) as much as one with a developer's own.
|
||||
execFileSync('git', ['init', '-q', dir])
|
||||
git(['config', 'user.name', 'Wall Entry Test'], dir)
|
||||
git(['config', 'user.email', 'wall-entry-test@example.com'], dir)
|
||||
remoteDir = initBareRemote()
|
||||
cacheDir = join(mkdtempSync(join(tmpdir(), 'wall-cache-')), 'soulcraft-releases')
|
||||
})
|
||||
|
|
|
|||
Reference in a new issue