diff --git a/.github/workflows/ci-subaction.yml b/.github/workflows/ci-subaction.yml index 0a9e85a..d881092 100644 --- a/.github/workflows/ci-subaction.yml +++ b/.github/workflows/ci-subaction.yml @@ -25,8 +25,15 @@ on: - 'test/**' jobs: - list-targets-group: + list-targets: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - testdir: group + - testdir: group-matrix + target: validate steps: - name: Checkout @@ -36,14 +43,26 @@ jobs: id: gen uses: ./subaction/list-targets with: - workdir: ./test/group - - - name: Show matrix - run: | - echo matrix=${{ steps.gen.outputs.matrix }} + workdir: ./test/${{ matrix.testdir }} + target: ${{ matrix.target }} - list-targets-group-matrix: + matrix: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - testdir: group + - testdir: group-matrix + target: validate + - testdir: group-with-platform + target: validate + - testdir: group-with-platform + target: validate + fields: platforms + - testdir: group-with-platform + target: validate + fields: platforms,dockerfile steps: - name: Checkout @@ -51,11 +70,8 @@ jobs: - name: Matrix gen id: gen - uses: ./subaction/list-targets + uses: ./subaction/matrix with: - workdir: ./test/group-matrix - target: validate - - - name: Show matrix - run: | - echo matrix=${{ steps.gen.outputs.matrix }} + workdir: ./test/${{ matrix.testdir }} + target: ${{ matrix.target }} + fields: ${{ matrix.fields }} diff --git a/subaction/matrix/action.yml b/subaction/matrix/action.yml new file mode 100644 index 0000000..76a62b9 --- /dev/null +++ b/subaction/matrix/action.yml @@ -0,0 +1,98 @@ +# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions +name: 'Matrix' +description: 'Generate a matrix from a Bake definition to help distributing builds in your workflow' + +inputs: + workdir: + description: Working directory + default: '.' + required: false + files: + description: List of Bake files + required: false + target: + description: Bake target + required: false + fields: + description: Comma separated list of extra fields to include in the matrix + required: false + +outputs: + matrix: + description: List of includes as matrix + value: ${{ steps.generate.outputs.includes }} + +runs: + using: composite + steps: + - + name: Generate + id: generate + uses: actions/github-script@v7 + with: + script: | + let def; + const files = `${{ inputs.files }}` ? `${{ inputs.files }}`.split('\n') : []; + const target = `${{ inputs.target }}`; + const fields = `${{ inputs.fields }}` ? `${{ inputs.fields }}`.split(',') : []; + + await core.group(`Parsing 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(`Generating matrix`, async () => { + let includes = []; + for (const targetName of Object.keys(def.target)) { + const target = def.target[targetName]; + if (fields.length > 0) { + let hasFields = false; + fields.forEach(field => { + if (target[field]) { + hasFields = true; + if (Array.isArray(target[field])) { + target[field].forEach(value => { + const include = { target: targetName }; + include[field] = value; + includes.push(include); + }); + } else { + const include = { target: targetName }; + include[field] = target[field]; + includes.push(include); + } + } else { + core.warning(`Field "${field}" not found in target ${targetName}`); + } + }); + if (!hasFields) { + includes.push({ + target: targetName + }); + } + } else { + includes.push({ + target: targetName + }); + } + } + core.info(JSON.stringify(includes, null, 2)); + core.setOutput('includes', JSON.stringify(includes)); + }); diff --git a/test/group-with-platform/docker-bake.hcl b/test/group-with-platform/docker-bake.hcl new file mode 100644 index 0000000..bfba830 --- /dev/null +++ b/test/group-with-platform/docker-bake.hcl @@ -0,0 +1,36 @@ +group "validate" { + targets = ["lint", "lint-gopls", "validate-vendor", "validate-docs"] +} + +target "lint" { + dockerfile = "./hack/dockerfiles/lint.Dockerfile" + output = ["type=cacheonly"] + platforms = [ + "darwin/amd64", + "darwin/arm64", + "linux/amd64", + "linux/arm64", + "linux/s390x", + "linux/ppc64le", + "linux/riscv64", + "windows/amd64", + "windows/arm64" + ] +} + +target "lint-gopls" { + inherits = ["lint"] + target = "gopls-analyze" +} + +target "validate-vendor" { + dockerfile = "./hack/dockerfiles/vendor.Dockerfile" + target = "validate" + output = ["type=cacheonly"] +} + +target "validate-docs" { + dockerfile = "./hack/dockerfiles/docs.Dockerfile" + target = "validate" + output = ["type=cacheonly"] +}