Skip to content

Commit dd3374e

Browse files
committed
buildx(build): support git context subdir and other query options
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
1 parent a8dc808 commit dd3374e

2 files changed

Lines changed: 56 additions & 11 deletions

File tree

__tests__/buildx/build.test.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ describe('gitContext', () => {
6464
prHeadRef: boolean;
6565
sendGitQueryAsInput: boolean;
6666
buildxQuerySupport: boolean;
67+
subdir?: string;
68+
keepGitDir?: boolean;
69+
submodules?: boolean;
6770
};
6871

6972
// prettier-ignore
@@ -79,28 +82,47 @@ describe('gitContext', () => {
7982
[{ref: 'refs/pull/15/merge', format: undefined, prHeadRef: false, sendGitQueryAsInput: true, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/merge&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
8083
[{ref: 'refs/pull/15/merge', format: undefined, prHeadRef: true, sendGitQueryAsInput: true, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/head&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
8184
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: true, buildxQuerySupport: false}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
85+
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, keepGitDir: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=1'],
86+
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: false, keepGitDir: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=1'],
87+
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, submodules: false}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
88+
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: false, submodules: false}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
8289
// query format
8390
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
8491
[{ref: 'master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
8592
[{ref: 'refs/pull/15/merge', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/merge&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
8693
[{ref: 'refs/tags/v1.0.0', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/tags/v1.0.0&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
8794
[{ref: 'refs/pull/15/merge', format: 'query', prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/head&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
95+
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir'}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&subdir=subdir'],
96+
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir', keepGitDir: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&subdir=subdir&keep-git-dir=1'],
97+
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, submodules: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=true'],
98+
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, submodules: false}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
8899
// fragment format
89100
[{ref: 'refs/heads/master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
90101
[{ref: 'master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
91102
[{ref: 'refs/pull/15/merge', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#refs/pull/15/merge'],
92103
[{ref: 'refs/tags/v1.0.0', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
93104
[{ref: 'refs/pull/15/merge', format: 'fragment', prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#refs/pull/15/head'],
105+
[{ref: 'refs/heads/master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir'}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37:subdir'],
106+
[{ref: 'refs/pull/15/merge', format: 'fragment', prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir'}, 'https://github.com/docker/actions-toolkit.git#refs/pull/15/head:subdir'],
94107
];
95108

96109
test.each(gitContextCases)('given %o should return %o', async (input: GitContextTestCase, expected: string) => {
97-
const {ref, format, prHeadRef, sendGitQueryAsInput, buildxQuerySupport} = input;
110+
const {ref, format, prHeadRef, sendGitQueryAsInput, buildxQuerySupport, subdir, keepGitDir, submodules} = input;
98111
process.env.DOCKER_DEFAULT_GIT_CONTEXT_PR_HEAD_REF = prHeadRef ? 'true' : '';
99112
process.env.BUILDX_SEND_GIT_QUERY_AS_INPUT = sendGitQueryAsInput ? 'true' : '';
100113
const buildx = new Buildx();
101114
vi.spyOn(buildx, 'versionSatisfies').mockResolvedValue(buildxQuerySupport);
102115
const build = new Build({buildx});
103-
expect(await build.gitContext(ref, '860c1904a1ce19322e91ac35af1ab07466440c37', format)).toEqual(expected);
116+
expect(
117+
await build.gitContext({
118+
ref,
119+
checksum: '860c1904a1ce19322e91ac35af1ab07466440c37',
120+
format,
121+
subdir,
122+
keepGitDir,
123+
submodules
124+
})
125+
).toEqual(expected);
104126
});
105127
});
106128

src/buildx/build.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ export interface ResolveSecretsOpts {
3838
redact?: boolean;
3939
}
4040

41+
export interface GitContextOpts {
42+
ref?: string;
43+
checksum?: string;
44+
subdir?: string;
45+
keepGitDir?: boolean;
46+
submodules?: boolean;
47+
format?: GitContextFormat;
48+
}
49+
4150
export class Build {
4251
private readonly buildx: Buildx;
4352
private readonly iidFilename: string;
@@ -49,31 +58,45 @@ export class Build {
4958
this.metadataFilename = `build-metadata-${Util.generateRandomString()}.json`;
5059
}
5160

52-
public async gitContext(ref?: string, sha?: string, format?: GitContextFormat): Promise<string> {
61+
public async gitContext(opts?: GitContextOpts): Promise<string> {
5362
const setPullRequestHeadRef = Util.parseBoolOrDefault(process.env.DOCKER_DEFAULT_GIT_CONTEXT_PR_HEAD_REF);
54-
ref = ref || github.context.ref;
55-
sha = sha || github.context.sha;
63+
const gitChecksum = opts?.checksum || github.context.sha;
64+
let ref = opts?.ref || github.context.ref;
5665
if (!ref.startsWith('refs/')) {
5766
ref = `refs/heads/${ref}`;
5867
} else if (ref.startsWith(`refs/pull/`) && setPullRequestHeadRef) {
5968
ref = ref.replace(/\/merge$/g, '/head');
6069
}
6170
const baseURL = `${GitHub.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}.git`;
71+
let format = opts?.format;
6272
if (!format) {
6373
const sendGitQueryAsInput = Util.parseBoolOrDefault(process.env.BUILDX_SEND_GIT_QUERY_AS_INPUT);
64-
if (sendGitQueryAsInput && (await this.buildx.versionSatisfies('>=0.29.0'))) {
74+
if (opts?.keepGitDir || typeof opts?.submodules !== 'undefined') {
75+
format = 'query';
76+
} else if (sendGitQueryAsInput && (await this.buildx.versionSatisfies('>=0.29.0'))) {
6577
format = 'query';
6678
} else {
6779
format = 'fragment';
6880
}
6981
}
7082
if (format === 'query') {
71-
return `${baseURL}?ref=${ref}${sha ? `&checksum=${sha}` : ''}`;
72-
}
73-
if (sha && !ref.startsWith(`refs/pull/`)) {
74-
return `${baseURL}#${sha}`;
83+
const query = [`ref=${ref}`];
84+
if (gitChecksum) {
85+
query.push(`checksum=${gitChecksum}`);
86+
}
87+
if (opts?.subdir) {
88+
query.push(`subdir=${opts.subdir}`);
89+
}
90+
if (opts?.keepGitDir) {
91+
query.push('keep-git-dir=1');
92+
}
93+
if (typeof opts?.submodules !== 'undefined') {
94+
query.push(`submodules=${opts.submodules}`);
95+
}
96+
return `${baseURL}?${query.join('&')}`;
7597
}
76-
return `${baseURL}#${ref}`;
98+
const fragmentRef = gitChecksum && !ref.startsWith(`refs/pull/`) ? gitChecksum : ref;
99+
return `${baseURL}#${fragmentRef}${opts?.subdir ? `:${opts.subdir}` : ''}`;
77100
}
78101

79102
public getImageIDFilePath(): string {

0 commit comments

Comments
 (0)