From 76ed7c58097ba6d6b8acdd3d9ecc3ce2406eb3ec Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Thu, 9 Nov 2023 11:07:49 +0100 Subject: [PATCH] list-targets subaction Signed-off-by: CrazyMax --- .github/workflows/ci-subaction.yml | 61 ++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 6 +++ .github/workflows/test.yml | 6 +++ .github/workflows/validate.yml | 6 +++ README.md | 60 +++++++++++++++++++++++++++++ subaction/list-targets/action.yml | 61 ++++++++++++++++++++++++++++++ test/group-matrix/docker-bake.hcl | 31 +++++++++++++++ 7 files changed, 231 insertions(+) create mode 100644 .github/workflows/ci-subaction.yml create mode 100644 subaction/list-targets/action.yml create mode 100644 test/group-matrix/docker-bake.hcl diff --git a/.github/workflows/ci-subaction.yml b/.github/workflows/ci-subaction.yml new file mode 100644 index 0000000..0a9e85a --- /dev/null +++ b/.github/workflows/ci-subaction.yml @@ -0,0 +1,61 @@ +name: ci-subaction + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + workflow_dispatch: + schedule: + - cron: '0 10 * * *' + push: + branches: + - 'master' + - 'releases/v*' + tags: + - 'v*' + paths: + - '.github/workflows/ci-subaction.yml' + - 'subaction/**' + - 'test/**' + pull_request: + paths: + - '.github/workflows/ci-subaction.yml' + - 'subaction/**' + - 'test/**' + +jobs: + list-targets-group: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Matrix gen + id: gen + uses: ./subaction/list-targets + with: + workdir: ./test/group + - + name: Show matrix + run: | + echo matrix=${{ steps.gen.outputs.matrix }} + + list-targets-group-matrix: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Matrix gen + id: gen + uses: ./subaction/list-targets + with: + workdir: ./test/group-matrix + target: validate + - + name: Show matrix + run: | + echo matrix=${{ steps.gen.outputs.matrix }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c772008..82ee44c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,13 @@ on: - 'releases/v*' tags: - 'v*' + paths-ignore: + - '.github/workflows/ci-subaction.yml' + - 'subaction/**' pull_request: + paths-ignore: + - '.github/workflows/ci-subaction.yml' + - 'subaction/**' env: BUILDX_VERSION: latest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e4e2a41..c989589 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,13 @@ on: branches: - 'master' - 'releases/v*' + paths-ignore: + - '.github/workflows/ci-subaction.yml' + - 'subaction/**' pull_request: + paths-ignore: + - '.github/workflows/ci-subaction.yml' + - 'subaction/**' jobs: test: diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 449d0c1..c0bfcab 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -9,7 +9,13 @@ on: branches: - 'master' - 'releases/v*' + paths-ignore: + - '.github/workflows/ci-subaction.yml' + - 'subaction/**' pull_request: + paths-ignore: + - '.github/workflows/ci-subaction.yml' + - 'subaction/**' jobs: prepare: diff --git a/README.md b/README.md index b256494..7d10e6d 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ as a high-level build command. ___ * [Usage](#usage) +* [Subactions](#subactions) + * [`list-targets`](#list-targets) * [Customizing](#customizing) * [inputs](#inputs) * [outputs](#outputs) @@ -52,6 +54,64 @@ jobs: push: true ``` +## Subactions + +### `list-targets` + +This subaction generates a list of Bake targets that can be used in a [GitHub matrix](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix), +so you can distribute your builds across multiple runners. + +```hcl +# docker-bake.hcl +group "validate" { + targets = ["lint", "doctoc"] +} + +target "lint" { + target = "lint" +} + +target "doctoc" { + target = "doctoc" +} +``` + +```yaml +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + targets: ${{ steps.matrix.outputs.targets }} + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Matrix + id: matrix + uses: docker/bake-action/subaction/list-targets@v4 + with: + target: validate + + validate: + runs-on: ubuntu-latest + needs: + - prepare + strategy: + fail-fast: false + matrix: + target: ${{ fromJson(needs.prepare.outputs.targets) }} + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Validate + uses: docker/bake-action@v4 + with: + targets: ${{ matrix.target }} +``` + ## Customizing ### inputs diff --git a/subaction/list-targets/action.yml b/subaction/list-targets/action.yml new file mode 100644 index 0000000..5d8f5e7 --- /dev/null +++ b/subaction/list-targets/action.yml @@ -0,0 +1,61 @@ +# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions +name: 'List Bake targets' +description: 'Generate a list of Bake targets to help distributing builds in your workflow' + +inputs: + workdir: + description: Working directory + default: '.' + required: false + files: + description: Comma separated list of Bake files + required: false + target: + description: Bake target + required: false + +outputs: + targets: + description: List of targets + value: ${{ steps.generate.outputs.targets }} + +runs: + using: composite + steps: + - + name: Generate + id: generate + uses: actions/github-script@v6 + with: + script: | + let def; + const files = `${{ inputs.files }}` ? `${{ inputs.files }}`.split(',') : []; + const target = `${{ inputs.target }}`; + + await core.group(`Validating definition`, async () => { + let args = ['buildx', 'bake']; + for (const file of files) { + args.push('--file', file); + } + if (target) { + args.push(target); + } + args.push('--print'); + + const res = await exec.getExecOutput('docker', args, { + ignoreReturnCode: true, + silent: true, + cwd: `${{ inputs.workdir }}` + }); + if (res.stderr.length > 0 && res.exitCode != 0) { + throw new Error(res.stderr); + } + def = JSON.parse(res.stdout.trim()); + core.info(JSON.stringify(def, null, 2)); + }); + + await core.group(`Set output`, async () => { + const targets = Object.keys(def.target); + core.info(`targets: ${JSON.stringify(targets)}`); + core.setOutput('targets', JSON.stringify(targets)); + }); diff --git a/test/group-matrix/docker-bake.hcl b/test/group-matrix/docker-bake.hcl new file mode 100644 index 0000000..ea27ff6 --- /dev/null +++ b/test/group-matrix/docker-bake.hcl @@ -0,0 +1,31 @@ +group "validate" { + targets = ["lint", "validate-vendor", "validate-doctoc"] +} + +target "lint" { + name = "lint-${buildtags.name}" + dockerfile = "./hack/dockerfiles/lint.Dockerfile" + target = buildtags.target + output = ["type=cacheonly"] + matrix = { + buildtags = [ + { name = "default", tags = "", target = "golangci-lint" }, + { name = "labs", tags = "dfrunsecurity dfparents", target = "golangci-lint" }, + { name = "nydus", tags = "nydus", target = "golangci-lint" }, + { name = "yaml", tags = "", target = "yamllint" }, + { name = "proto", tags = "", target = "protolint" }, + ] + } +} + +target "validate-vendor" { + dockerfile = "./hack/dockerfiles/vendor.Dockerfile" + target = "validate" + output = ["type=cacheonly"] +} + +target "validate-doctoc" { + dockerfile = "./hack/dockerfiles/doctoc.Dockerfile" + target = "validate-toc" + output = ["type=cacheonly"] +}