Skip to content

Commit 8e8fbbb

Browse files
committed
merge workdir into source input
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
1 parent 471133c commit 8e8fbbb

File tree

7 files changed

+131
-66
lines changed

7 files changed

+131
-66
lines changed

.github/workflows/ci.yml

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,27 @@ jobs:
121121
exit 1
122122
fi
123123
124+
error-source:
125+
runs-on: ubuntu-latest
126+
steps:
127+
-
128+
name: Checkout
129+
uses: actions/checkout@v6
130+
-
131+
name: Build
132+
id: bake
133+
continue-on-error: true
134+
uses: ./
135+
with:
136+
source: ./does-not-exist
137+
-
138+
name: Check
139+
run: |
140+
if [ "${{ steps.bake.outcome }}" != "failure" ] || [ "${{ steps.bake.conclusion }}" != "success" ]; then
141+
echo "::error::Should have failed"
142+
exit 1
143+
fi
144+
124145
standalone:
125146
runs-on: ubuntu-latest
126147
steps:
@@ -190,8 +211,7 @@ jobs:
190211
name: Build
191212
uses: ./
192213
with:
193-
workdir: ./test/go
194-
source: .
214+
source: ./test/go
195215
targets: binary
196216
provenance: ${{ matrix.attrs }}
197217
set: |
@@ -232,8 +252,7 @@ jobs:
232252
name: Build
233253
uses: ./
234254
with:
235-
workdir: ./test/go
236-
source: .
255+
source: ./test/go
237256
targets: ${{ matrix.target }}
238257
sbom: true
239258
set: |
@@ -279,8 +298,7 @@ jobs:
279298
name: Build
280299
uses: ./
281300
with:
282-
workdir: ./test/go
283-
source: .
301+
source: ./test/go
284302
set: |
285303
*.platform=linux/amd64
286304
*.output=type=image,"name=localhost:5000/name/app:v1.0.0,localhost:5000/name/app:latest",push=true
@@ -309,8 +327,7 @@ jobs:
309327
name: Build and push
310328
uses: ./
311329
with:
312-
workdir: ./test/group
313-
source: .
330+
source: ./test/group
314331
push: true
315332
set: |
316333
t1.tags=localhost:5000/name/app:t1
@@ -472,8 +489,7 @@ jobs:
472489
name: Build and push
473490
uses: ./
474491
with:
475-
workdir: ./test/go
476-
source: .
492+
source: ./test/go
477493
set: |
478494
*.output=type=image,name=localhost:5000/name/app:latest,push=true
479495
*.output=type=docker,name=app:local
@@ -516,8 +532,7 @@ jobs:
516532
name: Build and push
517533
uses: ./
518534
with:
519-
workdir: ./test/go
520-
source: .
535+
source: ./test/go
521536
targets: image
522537
load: true
523538
push: true
@@ -651,8 +666,7 @@ jobs:
651666
name: Build
652667
uses: ./
653668
with:
654-
workdir: ./test
655-
source: .
669+
source: ./test
656670
files: |
657671
./lint.hcl
658672
@@ -673,8 +687,7 @@ jobs:
673687
name: Build
674688
uses: ./
675689
with:
676-
workdir: ./test
677-
source: .
690+
source: ./test
678691
files: |
679692
./lint.hcl
680693
env:
@@ -745,8 +758,7 @@ jobs:
745758
continue-on-error: true
746759
uses: ./
747760
with:
748-
workdir: ./test
749-
source: .
761+
source: ./test
750762
files: |
751763
./lint.hcl
752764
call: check
@@ -778,8 +790,7 @@ jobs:
778790
continue-on-error: true
779791
uses: ./
780792
with:
781-
workdir: ./test
782-
source: .
793+
source: ./test
783794
files: |
784795
./lint.hcl
785796
call: check
@@ -832,5 +843,4 @@ jobs:
832843
name: Build and push
833844
uses: ./
834845
with:
835-
workdir: ./test/attest
836-
source: .
846+
source: ./test/attest

README.md

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ ___
2323
* [environment variables](#environment-variables)
2424
* [Subactions](#subactions)
2525
* [`matrix`](subaction/matrix)
26+
* [Notes](#notes)
27+
* [Source semantics](#source-semantics)
2628
* [Contributing](#contributing)
2729

2830
## Usage
@@ -143,6 +145,31 @@ jobs:
143145
*.tags=user/app:latest
144146
```
145147

148+
If you point `source` to a subdirectory, relative paths are resolved from that
149+
subdirectory:
150+
151+
```yaml
152+
-
153+
name: Build and push
154+
uses: docker/bake-action@v6
155+
with:
156+
source: ./subdir
157+
files: ./docker-bake.hcl
158+
```
159+
160+
For example, if `./subdir/docker-bake.hcl` contains:
161+
162+
```hcl
163+
target "default" {
164+
output = ["type=local,dest=./artifacts"]
165+
}
166+
```
167+
168+
The output will be written to `./subdir/artifacts` in the workspace.
169+
170+
> [!NOTE]
171+
> More info about `source` semantics in the [Source semantics](#source-semantics) section.
172+
146173
## Summaries
147174

148175
This action generates a [job summary](https://github.blog/2022-05-09-supercharging-github-actions-with-job-summaries/)
@@ -197,23 +224,22 @@ The following inputs can be used as `step.with` keys
197224
> targets: default,release
198225
> ```
199226

200-
| Name | Type | Description |
201-
|----------------|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
202-
| `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) |
203-
| `workdir` | String | Working directory of execution |
204-
| `source` | String | Context to build from. Can be either local (`.`) or a [remote bake definition](https://docs.docker.com/build/bake/remote-definition/) |
205-
| `allow` | List/CSV | Allow build to access specified resources (e.g., `network.host`) |
206-
| `call` | String | Set method for evaluating build (e.g., check) |
207-
| `files` | List/CSV | List of [bake definition files](https://docs.docker.com/build/customize/bake/file-definition/) |
208-
| `no-cache` | Bool | Do not use cache when building the image (default `false`) |
209-
| `pull` | Bool | Always attempt to pull a newer version of the image (default `false`) |
210-
| `load` | Bool | Load is a shorthand for `--set=*.output=type=docker` (default `false`) |
211-
| `provenance` | Bool/String | [Provenance](https://docs.docker.com/build/attestations/slsa-provenance/) is a shorthand for `--set=*.attest=type=provenance` |
212-
| `push` | Bool | Push is a shorthand for `--set=*.output=type=registry` (default `false`) |
213-
| `sbom` | Bool/String | [SBOM](https://docs.docker.com/build/attestations/sbom/) is a shorthand for `--set=*.attest=type=sbom` |
214-
| `set` | List | List of [targets values to override](https://docs.docker.com/engine/reference/commandline/buildx_bake/#set) (e.g., `targetpattern.key=value`) |
215-
| `targets` | List/CSV | List of bake targets (`default` target used if empty) |
216-
| `github-token` | String | API token used to authenticate to a Git repository for [remote definitions](https://docs.docker.com/build/bake/remote-definition/) (default `${{ github.token }}`) |
227+
| Name | Type | Description |
228+
|----------------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
229+
| `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) |
230+
| `allow` | List/CSV | Allow build to access specified resources (e.g., `network.host`) |
231+
| `call` | String | Set method for evaluating build (e.g., check) |
232+
| `files` | List/CSV | List of [bake definition files](https://docs.docker.com/build/customize/bake/file-definition/) |
233+
| `no-cache` | Bool | Do not use cache when building the image (default `false`) |
234+
| `pull` | Bool | Always attempt to pull a newer version of the image (default `false`) |
235+
| `load` | Bool | Load is a shorthand for `--set=*.output=type=docker` (default `false`) |
236+
| `provenance` | Bool/String | [Provenance](https://docs.docker.com/build/attestations/slsa-provenance/) is a shorthand for `--set=*.attest=type=provenance` |
237+
| `push` | Bool | Push is a shorthand for `--set=*.output=type=registry` (default `false`) |
238+
| `sbom` | Bool/String | [SBOM](https://docs.docker.com/build/attestations/sbom/) is a shorthand for `--set=*.attest=type=sbom` |
239+
| `set` | List | List of [targets values to override](https://docs.docker.com/engine/reference/commandline/buildx_bake/#set) (e.g., `targetpattern.key=value`) |
240+
| `source` | String | Build source to use. Supports local path and [remote bake definition](https://docs.docker.com/build/bake/remote-definition/). With a local path, Bake runs from that directory, so all relative paths are resolved from it. See [Source semantics](#source-semantics). |
241+
| `targets` | List/CSV | List of bake targets (`default` target used if empty) |
242+
| `github-token` | String | API token used to authenticate to a Git repository for [remote definitions](https://docs.docker.com/build/bake/remote-definition/) (default `${{ github.token }}`) |
217243

218244
### outputs
219245

@@ -236,6 +262,23 @@ The following outputs are available
236262

237263
* [`matrix`](subaction/matrix)
238264

265+
## Notes
266+
267+
### Source semantics
268+
269+
`source` accepts either a Git/remote bake definition (for example `{{defaultContext}}` or `{{defaultContext}}:subdir`)
270+
or a local path (for example `.` or `./subdir`). When `source` is a local path,
271+
the action runs Bake from that directory (equivalent to `cd <path> && docker buildx bake`).
272+
273+
This local path mode affects all relative paths resolved by Bake, not only
274+
target `context` fields. This includes paths used by local outputs, cache
275+
import/export, and `cwd://` references.
276+
277+
| `source` | Behavior |
278+
|-----------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
279+
| Git/remote (`{{defaultContext}}`, `https://...git#ref`, `...:subdir`) | Uses [remote bake definition](https://docs.docker.com/build/bake/remote-definition/) behavior. |
280+
| Local path (`.`, `./subdir`) | Changes Bake working directory to that path before invoking Bake. |
281+
239282
## Contributing
240283

241284
Want to contribute? Awesome! You can find information about contributing to

__tests__/context.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,11 @@ describe('getArgs', () => {
368368
provenance: inp.provenance,
369369
push: inp.push,
370370
sbom: inp.sbom,
371-
source: inp.source,
371+
source: inp.source.remoteRef,
372372
targets: inp.targets
373373
},
374374
{
375-
cwd: inp.workdir
375+
cwd: inp.source.workdir,
376376
}
377377
);
378378
const res = await context.getArgs(inp, definition, toolkit);

action.yml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@ inputs:
1010
builder:
1111
description: "Builder instance"
1212
required: false
13-
workdir:
14-
description: "Working directory of bake execution"
15-
required: false
16-
default: '.'
17-
source:
18-
description: "Context to build from. Can be either local or a remote bake definition"
19-
required: false
2013
allow:
2114
description: "Allow build to access specified resources (e.g., network.host)"
2215
required: false
@@ -51,6 +44,9 @@ inputs:
5144
set:
5245
description: "List of targets values to override (eg. targetpattern.key=value)"
5346
required: false
47+
source:
48+
description: "Context to build from. Can be either local to specify the working directory or a remote bake definition"
49+
required: false
5450
targets:
5551
description: "List of bake targets"
5652
required: false

src/context.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as fs from 'fs';
12
import * as core from '@actions/core';
23
import * as handlebars from 'handlebars';
34

@@ -10,10 +11,13 @@ import {Util} from '@docker/actions-toolkit/lib/util.js';
1011

1112
import {BakeDefinition} from '@docker/actions-toolkit/lib/types/buildx/bake.js';
1213

14+
export interface BakeContext {
15+
remoteRef?: string;
16+
workdir?: string;
17+
}
18+
1319
export interface Inputs {
1420
builder: string;
15-
workdir: string;
16-
source: string;
1721
allow: string[];
1822
call: string;
1923
files: string[];
@@ -24,15 +28,14 @@ export interface Inputs {
2428
push: boolean;
2529
sbom: string;
2630
set: string[];
31+
source: BakeContext;
2732
targets: string[];
2833
'github-token': string;
2934
}
3035

3136
export async function getInputs(): Promise<Inputs> {
3237
return {
3338
builder: core.getInput('builder'),
34-
workdir: core.getInput('workdir') || '.',
35-
source: getSourceInput('source'),
3639
allow: Util.getInputList('allow'),
3740
call: core.getInput('call'),
3841
files: Util.getInputList('files'),
@@ -43,6 +46,7 @@ export async function getInputs(): Promise<Inputs> {
4346
push: core.getBooleanInput('push'),
4447
sbom: core.getInput('sbom'),
4548
set: Util.getInputList('set', {ignoreComma: true, quote: false}),
49+
source: getBakeContext(core.getInput('source')),
4650
targets: Util.getInputList('targets'),
4751
'github-token': core.getInput('github-token')
4852
};
@@ -59,8 +63,8 @@ export async function getArgs(inputs: Inputs, definition: BakeDefinition, toolki
5963

6064
async function getBakeArgs(inputs: Inputs, definition: BakeDefinition, toolkit: Toolkit): Promise<Array<string>> {
6165
const args: Array<string> = ['bake'];
62-
if (inputs.source) {
63-
args.push(inputs.source);
66+
if (inputs.source.remoteRef) {
67+
args.push(inputs.source.remoteRef);
6468
}
6569
if (await toolkit.buildx.versionSatisfies('>=0.17.0')) {
6670
if (await toolkit.buildx.versionSatisfies('>=0.18.0')) {
@@ -135,17 +139,26 @@ async function getCommonArgs(inputs: Inputs): Promise<Array<string>> {
135139
return args;
136140
}
137141

138-
function getSourceInput(name: string): string {
139-
let source = handlebars.compile(core.getInput(name))({
142+
function getBakeContext(sourceInput: string): BakeContext {
143+
let bakeContext = handlebars.compile(sourceInput)({
140144
defaultContext: Context.gitContext()
141145
});
142-
if (!source) {
143-
source = Context.gitContext();
146+
if (!bakeContext) {
147+
bakeContext = Context.gitContext();
148+
}
149+
if (Util.isValidRef(bakeContext)) {
150+
return {
151+
remoteRef: bakeContext
152+
};
144153
}
145-
if (source === '.') {
146-
source = '';
154+
try {
155+
fs.statSync(sourceInput).isDirectory();
156+
} catch {
157+
throw new Error(`Invalid source: ${sourceInput} does not exist or is not a directory.`);
147158
}
148-
return source;
159+
return {
160+
workdir: bakeContext
161+
};
149162
}
150163

151164
function noDefaultAttestations(): boolean {

0 commit comments

Comments
 (0)