merge workdir into source input

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2026-01-07 16:50:58 +01:00
parent 471133c110
commit 8e8fbbb910
7 changed files with 131 additions and 66 deletions

View File

@@ -121,6 +121,27 @@ jobs:
exit 1
fi
error-source:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v6
-
name: Build
id: bake
continue-on-error: true
uses: ./
with:
source: ./does-not-exist
-
name: Check
run: |
if [ "${{ steps.bake.outcome }}" != "failure" ] || [ "${{ steps.bake.conclusion }}" != "success" ]; then
echo "::error::Should have failed"
exit 1
fi
standalone:
runs-on: ubuntu-latest
steps:
@@ -190,8 +211,7 @@ jobs:
name: Build
uses: ./
with:
workdir: ./test/go
source: .
source: ./test/go
targets: binary
provenance: ${{ matrix.attrs }}
set: |
@@ -232,8 +252,7 @@ jobs:
name: Build
uses: ./
with:
workdir: ./test/go
source: .
source: ./test/go
targets: ${{ matrix.target }}
sbom: true
set: |
@@ -279,8 +298,7 @@ jobs:
name: Build
uses: ./
with:
workdir: ./test/go
source: .
source: ./test/go
set: |
*.platform=linux/amd64
*.output=type=image,"name=localhost:5000/name/app:v1.0.0,localhost:5000/name/app:latest",push=true
@@ -309,8 +327,7 @@ jobs:
name: Build and push
uses: ./
with:
workdir: ./test/group
source: .
source: ./test/group
push: true
set: |
t1.tags=localhost:5000/name/app:t1
@@ -472,8 +489,7 @@ jobs:
name: Build and push
uses: ./
with:
workdir: ./test/go
source: .
source: ./test/go
set: |
*.output=type=image,name=localhost:5000/name/app:latest,push=true
*.output=type=docker,name=app:local
@@ -516,8 +532,7 @@ jobs:
name: Build and push
uses: ./
with:
workdir: ./test/go
source: .
source: ./test/go
targets: image
load: true
push: true
@@ -651,8 +666,7 @@ jobs:
name: Build
uses: ./
with:
workdir: ./test
source: .
source: ./test
files: |
./lint.hcl
@@ -673,8 +687,7 @@ jobs:
name: Build
uses: ./
with:
workdir: ./test
source: .
source: ./test
files: |
./lint.hcl
env:
@@ -745,8 +758,7 @@ jobs:
continue-on-error: true
uses: ./
with:
workdir: ./test
source: .
source: ./test
files: |
./lint.hcl
call: check
@@ -778,8 +790,7 @@ jobs:
continue-on-error: true
uses: ./
with:
workdir: ./test
source: .
source: ./test
files: |
./lint.hcl
call: check
@@ -832,5 +843,4 @@ jobs:
name: Build and push
uses: ./
with:
workdir: ./test/attest
source: .
source: ./test/attest

View File

@@ -23,6 +23,8 @@ ___
* [environment variables](#environment-variables)
* [Subactions](#subactions)
* [`matrix`](subaction/matrix)
* [Notes](#notes)
* [Source semantics](#source-semantics)
* [Contributing](#contributing)
## Usage
@@ -143,6 +145,31 @@ jobs:
*.tags=user/app:latest
```
If you point `source` to a subdirectory, relative paths are resolved from that
subdirectory:
```yaml
-
name: Build and push
uses: docker/bake-action@v6
with:
source: ./subdir
files: ./docker-bake.hcl
```
For example, if `./subdir/docker-bake.hcl` contains:
```hcl
target "default" {
output = ["type=local,dest=./artifacts"]
}
```
The output will be written to `./subdir/artifacts` in the workspace.
> [!NOTE]
> More info about `source` semantics in the [Source semantics](#source-semantics) section.
## Summaries
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
> targets: default,release
> ```
| Name | Type | Description |
|----------------|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) |
| `workdir` | String | Working directory of execution |
| `source` | String | Context to build from. Can be either local (`.`) or a [remote bake definition](https://docs.docker.com/build/bake/remote-definition/) |
| `allow` | List/CSV | Allow build to access specified resources (e.g., `network.host`) |
| `call` | String | Set method for evaluating build (e.g., check) |
| `files` | List/CSV | List of [bake definition files](https://docs.docker.com/build/customize/bake/file-definition/) |
| `no-cache` | Bool | Do not use cache when building the image (default `false`) |
| `pull` | Bool | Always attempt to pull a newer version of the image (default `false`) |
| `load` | Bool | Load is a shorthand for `--set=*.output=type=docker` (default `false`) |
| `provenance` | Bool/String | [Provenance](https://docs.docker.com/build/attestations/slsa-provenance/) is a shorthand for `--set=*.attest=type=provenance` |
| `push` | Bool | Push is a shorthand for `--set=*.output=type=registry` (default `false`) |
| `sbom` | Bool/String | [SBOM](https://docs.docker.com/build/attestations/sbom/) is a shorthand for `--set=*.attest=type=sbom` |
| `set` | List | List of [targets values to override](https://docs.docker.com/engine/reference/commandline/buildx_bake/#set) (e.g., `targetpattern.key=value`) |
| `targets` | List/CSV | List of bake targets (`default` target used if empty) |
| `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 }}`) |
| Name | Type | Description |
|----------------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) |
| `allow` | List/CSV | Allow build to access specified resources (e.g., `network.host`) |
| `call` | String | Set method for evaluating build (e.g., check) |
| `files` | List/CSV | List of [bake definition files](https://docs.docker.com/build/customize/bake/file-definition/) |
| `no-cache` | Bool | Do not use cache when building the image (default `false`) |
| `pull` | Bool | Always attempt to pull a newer version of the image (default `false`) |
| `load` | Bool | Load is a shorthand for `--set=*.output=type=docker` (default `false`) |
| `provenance` | Bool/String | [Provenance](https://docs.docker.com/build/attestations/slsa-provenance/) is a shorthand for `--set=*.attest=type=provenance` |
| `push` | Bool | Push is a shorthand for `--set=*.output=type=registry` (default `false`) |
| `sbom` | Bool/String | [SBOM](https://docs.docker.com/build/attestations/sbom/) is a shorthand for `--set=*.attest=type=sbom` |
| `set` | List | List of [targets values to override](https://docs.docker.com/engine/reference/commandline/buildx_bake/#set) (e.g., `targetpattern.key=value`) |
| `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). |
| `targets` | List/CSV | List of bake targets (`default` target used if empty) |
| `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 }}`) |
### outputs
@@ -236,6 +262,23 @@ The following outputs are available
* [`matrix`](subaction/matrix)
## Notes
### Source semantics
`source` accepts either a Git/remote bake definition (for example `{{defaultContext}}` or `{{defaultContext}}:subdir`)
or a local path (for example `.` or `./subdir`). When `source` is a local path,
the action runs Bake from that directory (equivalent to `cd <path> && docker buildx bake`).
This local path mode affects all relative paths resolved by Bake, not only
target `context` fields. This includes paths used by local outputs, cache
import/export, and `cwd://` references.
| `source` | Behavior |
|-----------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| Git/remote (`{{defaultContext}}`, `https://...git#ref`, `...:subdir`) | Uses [remote bake definition](https://docs.docker.com/build/bake/remote-definition/) behavior. |
| Local path (`.`, `./subdir`) | Changes Bake working directory to that path before invoking Bake. |
## Contributing
Want to contribute? Awesome! You can find information about contributing to

View File

@@ -368,11 +368,11 @@ describe('getArgs', () => {
provenance: inp.provenance,
push: inp.push,
sbom: inp.sbom,
source: inp.source,
source: inp.source.remoteRef,
targets: inp.targets
},
{
cwd: inp.workdir
cwd: inp.source.workdir,
}
);
const res = await context.getArgs(inp, definition, toolkit);

View File

@@ -10,13 +10,6 @@ inputs:
builder:
description: "Builder instance"
required: false
workdir:
description: "Working directory of bake execution"
required: false
default: '.'
source:
description: "Context to build from. Can be either local or a remote bake definition"
required: false
allow:
description: "Allow build to access specified resources (e.g., network.host)"
required: false
@@ -51,6 +44,9 @@ inputs:
set:
description: "List of targets values to override (eg. targetpattern.key=value)"
required: false
source:
description: "Context to build from. Can be either local to specify the working directory or a remote bake definition"
required: false
targets:
description: "List of bake targets"
required: false

View File

@@ -1,3 +1,4 @@
import * as fs from 'fs';
import * as core from '@actions/core';
import * as handlebars from 'handlebars';
@@ -10,10 +11,13 @@ import {Util} from '@docker/actions-toolkit/lib/util.js';
import {BakeDefinition} from '@docker/actions-toolkit/lib/types/buildx/bake.js';
export interface BakeContext {
remoteRef?: string;
workdir?: string;
}
export interface Inputs {
builder: string;
workdir: string;
source: string;
allow: string[];
call: string;
files: string[];
@@ -24,6 +28,7 @@ export interface Inputs {
push: boolean;
sbom: string;
set: string[];
source: BakeContext;
targets: string[];
'github-token': string;
}
@@ -31,8 +36,6 @@ export interface Inputs {
export async function getInputs(): Promise<Inputs> {
return {
builder: core.getInput('builder'),
workdir: core.getInput('workdir') || '.',
source: getSourceInput('source'),
allow: Util.getInputList('allow'),
call: core.getInput('call'),
files: Util.getInputList('files'),
@@ -43,6 +46,7 @@ export async function getInputs(): Promise<Inputs> {
push: core.getBooleanInput('push'),
sbom: core.getInput('sbom'),
set: Util.getInputList('set', {ignoreComma: true, quote: false}),
source: getBakeContext(core.getInput('source')),
targets: Util.getInputList('targets'),
'github-token': core.getInput('github-token')
};
@@ -59,8 +63,8 @@ export async function getArgs(inputs: Inputs, definition: BakeDefinition, toolki
async function getBakeArgs(inputs: Inputs, definition: BakeDefinition, toolkit: Toolkit): Promise<Array<string>> {
const args: Array<string> = ['bake'];
if (inputs.source) {
args.push(inputs.source);
if (inputs.source.remoteRef) {
args.push(inputs.source.remoteRef);
}
if (await toolkit.buildx.versionSatisfies('>=0.17.0')) {
if (await toolkit.buildx.versionSatisfies('>=0.18.0')) {
@@ -135,17 +139,26 @@ async function getCommonArgs(inputs: Inputs): Promise<Array<string>> {
return args;
}
function getSourceInput(name: string): string {
let source = handlebars.compile(core.getInput(name))({
function getBakeContext(sourceInput: string): BakeContext {
let bakeContext = handlebars.compile(sourceInput)({
defaultContext: Context.gitContext()
});
if (!source) {
source = Context.gitContext();
if (!bakeContext) {
bakeContext = Context.gitContext();
}
if (source === '.') {
source = '';
if (Util.isValidRef(bakeContext)) {
return {
remoteRef: bakeContext
};
}
return source;
try {
fs.statSync(sourceInput).isDirectory();
} catch {
throw new Error(`Invalid source: ${sourceInput} does not exist or is not a directory.`);
}
return {
workdir: bakeContext
};
}
function noDefaultAttestations(): boolean {

View File

@@ -107,12 +107,12 @@ actionsToolkit.run(
provenance: inputs.provenance,
push: inputs.push,
sbom: inputs.sbom,
source: inputs.source,
source: inputs.source.remoteRef,
targets: inputs.targets,
githubToken: gitAuthToken
},
{
cwd: inputs.workdir
cwd: inputs.source.workdir
}
);
});
@@ -132,7 +132,7 @@ actionsToolkit.run(
await core.group(`Bake definition`, async () => {
await Exec.getExecOutput(buildCmd.command, [...buildCmd.args, '--print'], {
cwd: inputs.workdir,
cwd: inputs.source.workdir,
env: buildEnv,
ignoreReturnCode: true
}).then(res => {
@@ -144,7 +144,7 @@ actionsToolkit.run(
let err: Error | undefined;
await Exec.getExecOutput(buildCmd.command, buildCmd.args, {
cwd: inputs.workdir,
cwd: inputs.source.workdir,
env: buildEnv,
ignoreReturnCode: true
}).then(res => {

View File

@@ -40,8 +40,11 @@ export function setSummarySupported() {
export function setSummaryInputs(inputs: Inputs) {
const res = {};
if (inputs.source.remoteRef || inputs.source.workdir) {
res['source'] = inputs.source.remoteRef || inputs.source.workdir;
}
for (const key of Object.keys(inputs)) {
if (key === 'github-token') {
if (key === 'source' || key === 'github-token') {
continue;
}
const value: string | string[] | boolean = inputs[key];