Skip to content

Commit 4386736

Browse files
authored
Merge pull request #1085 from crazy-max/git-context-pin
buildx(build): pin implicit git contexts consistently
2 parents b7f80a0 + f57dfd2 commit 4386736

2 files changed

Lines changed: 41 additions & 39 deletions

File tree

__tests__/buildx/build.test.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,40 +90,43 @@ describe('gitContext', () => {
9090
[{ref: 'refs/tags/v1.0.0', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
9191
[{ref: 'refs/pull/15/merge', checksum: undefined, format: undefined, prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#f11797113e5a9b86bd976329c5dbb8a8bfdfadfa'],
9292
// no format set (defaults to query only when client-side query resolution is enabled and supported)
93-
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: true, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
93+
[{ref: 'refs/heads/master', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: true, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37'],
9494
[{ref: 'refs/pull/15/merge', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: true, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37'],
9595
[{ref: 'refs/pull/15/merge', checksum: undefined, format: undefined, prHeadRef: true, sendGitQueryAsInput: true, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=f11797113e5a9b86bd976329c5dbb8a8bfdfadfa'],
9696
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: true, buildxQuerySupport: false}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
9797
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {}}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
9898
[{ref: 'refs/heads/master', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {checksum: 'cafebabe'}}, 'https://github.com/docker/actions-toolkit.git#cafebabe'],
9999
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {subdir: 'subdir'}}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37:subdir'],
100100
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {ref: 'refs/tags/v1.0.0'}}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
101-
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true'],
102-
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: false, attrs: {'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true'],
101+
[{ref: 'refs/heads/master', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true'],
102+
[{ref: 'refs/heads/master', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: false, attrs: {'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true'],
103103
[{ref: 'refs/heads/master', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {checksum: 'cafebabe', 'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=cafebabe&keep-git-dir=true'],
104-
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
105-
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: false, attrs: {submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
104+
[{ref: 'refs/heads/master', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
105+
[{ref: 'refs/heads/master', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: false, attrs: {submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
106106
// query format
107-
[{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'],
108-
[{ref: 'master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
107+
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37'],
108+
[{ref: 'master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37'],
109109
[{ref: 'refs/pull/15/merge', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37'],
110-
[{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'],
110+
[{ref: 'refs/tags/v1.0.0', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37'],
111111
[{ref: 'refs/pull/15/merge', checksum: undefined, format: 'query', prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=f11797113e5a9b86bd976329c5dbb8a8bfdfadfa'],
112112
[{ref: 'refs/pull/15/merge', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {checksum: 'cafebabe'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/merge&checksum=cafebabe'],
113-
[{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'],
114-
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: '.'}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
113+
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir'}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&subdir=subdir'],
114+
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: '.'}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37'],
115115
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {ref: 'refs/tags/v1.0.0', checksum: 'cafebabe', subdir: 'subdir', submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=cafebabe&subdir=subdir&submodules=false'],
116-
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir', attrs: {'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&subdir=subdir&keep-git-dir=true'],
117-
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {submodules: 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=true'],
118-
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
119-
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'keep-git-dir': 'true', submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true&submodules=false'],
116+
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir', attrs: {'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&subdir=subdir&keep-git-dir=true'],
117+
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {submodules: 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=true'],
118+
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
119+
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'keep-git-dir': 'true', submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true&submodules=false'],
120+
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'fetch-by-commit': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&fetch-by-commit=true'],
121+
[{ref: 'refs/pull/15/merge', checksum: undefined, format: 'query', prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'fetch-by-commit': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/head&checksum=f11797113e5a9b86bd976329c5dbb8a8bfdfadfa&fetch-by-commit=true'],
122+
[{ref: 'refs/heads/master', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'fetch-by-commit': 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=860c1904a1ce19322e91ac35af1ab07466440c37&fetch-by-commit=false'],
120123
// fragment format
121124
[{ref: 'refs/heads/master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
122125
[{ref: 'master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
123126
[{ref: 'refs/pull/15/merge', checksum: undefined, format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
124127
[{ref: 'refs/tags/v1.0.0', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
125128
[{ref: 'refs/pull/15/merge', checksum: undefined, format: 'fragment', prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#f11797113e5a9b86bd976329c5dbb8a8bfdfadfa'],
126-
[{ref: 'refs/pull/15/merge', checksum: undefined, format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {checksum: 'cafebabe'}}, 'https://github.com/docker/actions-toolkit.git#refs/pull/15/merge'],
129+
[{ref: 'refs/pull/15/merge', checksum: undefined, format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {checksum: 'cafebabe'}}, 'https://github.com/docker/actions-toolkit.git#cafebabe'],
127130
[{ref: 'refs/heads/master', checksum: undefined, format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {checksum: 'cafebabe', subdir: 'subdir', ref: 'refs/tags/v1.0.0'}}, 'https://github.com/docker/actions-toolkit.git#cafebabe:subdir'],
128131
[{ref: 'refs/heads/master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
129132
[{ref: 'refs/heads/master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir'}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37:subdir'],

src/buildx/build.ts

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export class Build {
6161
const gitContextCommonAttrs = new Set(['ref', 'checksum', 'subdir']);
6262
const commonAttrs = opts?.attrs || {};
6363
const extraAttrs = Object.entries(commonAttrs).filter(([name]) => !gitContextCommonAttrs.has(name));
64+
const fetchByCommit = Util.parseBoolOrDefault(commonAttrs['fetch-by-commit']);
6465

6566
let ref = opts?.ref || commonAttrs.ref || github.context.ref;
6667
if (!ref.startsWith('refs/')) {
@@ -69,23 +70,10 @@ export class Build {
6970
ref = ref.replace(/\/merge$/g, '/head');
7071
}
7172

72-
const inputChecksum = opts?.checksum || commonAttrs.checksum;
73-
const inputSubdir = opts?.subdir || commonAttrs.subdir;
74-
const checksum = inputChecksum || (ref.startsWith(`refs/pull/`) ? undefined : github.context.sha);
75-
76-
// BuildKit resolves PR refs remotely at build time, so mutable refs like
77-
// refs/pull/*/{merge,head} can drift away from the event SHA. actions/checkout
78-
// avoids that by fetching the exact commit into a local PR ref; here we do the
79-
// equivalent for implicit PR contexts by rewriting them to the event's commit SHA.
80-
if (!inputChecksum && ref.startsWith(`refs/pull/`)) {
81-
if (ref.endsWith('/merge')) {
82-
ref = github.context.sha;
83-
} else if (ref.endsWith('/head') && typeof github.context.payload.pull_request?.head?.sha === 'string') {
84-
ref = github.context.payload.pull_request.head.sha;
85-
}
86-
}
87-
8873
const baseURL = `${GitHub.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}.git`;
74+
const explicitChecksum = opts?.checksum || commonAttrs.checksum;
75+
const subdir = opts?.subdir || commonAttrs.subdir;
76+
8977
let format = opts?.format;
9078
if (!format) {
9179
format = 'fragment';
@@ -97,27 +85,38 @@ export class Build {
9785
format = 'query';
9886
}
9987
} catch {
100-
// keep fragment fallback when Buildx version cannot be determined.
88+
// Keep fragment fallback when Buildx version cannot be determined.
10189
}
10290
}
10391
}
10492

93+
// Implicit git contexts should resolve to the event commit. PR head refs
94+
// pin the pull request head SHA instead of the merge commit SHA.
95+
let implicitRef = github.context.sha || ref;
96+
if (ref.startsWith(`refs/pull/`) && ref.endsWith('/head')) {
97+
implicitRef = typeof github.context.payload.pull_request?.head?.sha === 'string' ? github.context.payload.pull_request.head.sha : ref;
98+
}
99+
const pinnedRef = explicitChecksum || implicitRef;
100+
105101
if (format === 'query') {
106-
const query = [`ref=${ref}`];
107-
if (checksum) {
108-
query.push(`checksum=${checksum}`);
102+
// Only use fetch-by-commit when the caller opts in; older BuildKit
103+
// versions do not know this query key. Without it, use the pinned commit
104+
// as the ref to keep existing compatibility.
105+
const query = [`ref=${fetchByCommit || explicitChecksum ? ref : pinnedRef}`];
106+
const queryChecksum = fetchByCommit ? pinnedRef : explicitChecksum;
107+
if (queryChecksum) {
108+
query.push(`checksum=${queryChecksum}`);
109109
}
110-
if (inputSubdir && inputSubdir !== '.') {
111-
query.push(`subdir=${inputSubdir}`);
110+
if (subdir && subdir !== '.') {
111+
query.push(`subdir=${subdir}`);
112112
}
113113
for (const [name, value] of extraAttrs) {
114114
query.push(`${name}=${value}`);
115115
}
116116
return `${baseURL}?${query.join('&')}`;
117117
}
118118

119-
const fragmentRef = inputChecksum && ref.startsWith(`refs/pull/`) ? ref : (checksum ?? ref);
120-
return `${baseURL}#${fragmentRef}${inputSubdir && inputSubdir !== '.' ? `:${inputSubdir}` : ''}`;
119+
return `${baseURL}#${pinnedRef}${subdir && subdir !== '.' ? `:${subdir}` : ''}`;
121120
}
122121

123122
public getImageIDFilePath(): string {

0 commit comments

Comments
 (0)