@@ -44,11 +44,29 @@ export async function withTmp(fn: (dir: string) => Promise<void>): Promise<void>
4444 }
4545}
4646
47+ // Ref to pin in test manifests. CI isn't always on `main` (feature-branch and
48+ // detached-HEAD PR builds are common), so resolve REPO_ROOT's real state: its
49+ // branch if checked out on one, else the HEAD commit. Both resolve in the clone
50+ // — a branch via origin/<branch>, a SHA directly (a local-path clone copies the
51+ // full object store, so even a detached commit is present).
52+ async function repoRef ( ) : Promise < string > {
53+ const git = async ( ...args : string [ ] ) : Promise < string > => {
54+ const { code, stdout } = await new Deno . Command ( "git" , {
55+ args : [ "-C" , REPO_ROOT , ...args ] ,
56+ stdout : "piped" ,
57+ stderr : "null" ,
58+ } ) . output ( ) ;
59+ return code === 0 ? new TextDecoder ( ) . decode ( stdout ) . trim ( ) : "" ;
60+ } ;
61+ return ( await git ( "branch" , "--show-current" ) ) || ( await git ( "rev-parse" , "HEAD" ) ) || "main" ;
62+ }
63+
4764// A decker.ts manifest pinned at the local checkout, so pull/auto-pull e2e runs
4865// offline and fast instead of hitting GitHub.
4966export async function writeLocalManifest ( dir : string , recipe = "l1" ) : Promise < void > {
67+ const ref = await repoRef ( ) ;
5068 const body = `type P = { decker: { source: string; ref: string; into?: string }; recipe: string };
51- export const project: P = { decker: { source: ${ JSON . stringify ( REPO_ROOT ) } , ref: "main" , into: ".decker" }, recipe: ${ JSON . stringify ( recipe ) } };
69+ export const project: P = { decker: { source: ${ JSON . stringify ( REPO_ROOT ) } , ref: ${ JSON . stringify ( ref ) } , into: ".decker" }, recipe: ${ JSON . stringify ( recipe ) } };
5270` ;
5371 await Deno . writeTextFile ( join ( dir , "decker.ts" ) , body ) ;
5472}
0 commit comments