From 1d0eb45ff982b67f9069fafd55f7ee41a4eec6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciek=20Go=C5=82aszewski?= Date: Wed, 7 Aug 2024 15:24:33 +0200 Subject: [PATCH] Only build and publish new ROCK version if rockfile.yaml changed (#16) --- .github/workflows/build_rocks.yaml | 115 ++++++++++++++++++----------- 1 file changed, 71 insertions(+), 44 deletions(-) diff --git a/.github/workflows/build_rocks.yaml b/.github/workflows/build_rocks.yaml index d8b8207..2316495 100644 --- a/.github/workflows/build_rocks.yaml +++ b/.github/workflows/build_rocks.yaml @@ -69,6 +69,9 @@ on: rock-metas: description: List of maps featuring the built {name, version, path, arch, image} value: ${{ jobs.get-rocks.outputs.rock-metas }} + changed-rock-metas: + description: List of maps featuring the built that has changed {name, version, path, arch, image} + value: ${{ jobs.get-rocks.outputs.changed-rock-metas }} jobs: get-rocks: @@ -78,6 +81,7 @@ jobs: rock-paths: ${{ steps.gen-rock-paths-and-images.outputs.rock-paths }} images: "${{ steps.gen-rock-paths-and-images.outputs.images }}" rock-metas: ${{ steps.gen-rock-paths-and-images.outputs.rock-metas }} + changed-rock-metas: ${{ steps.gen-rock-paths-and-images.outputs.changed-rock-metas }} steps: - name: Validate inputs run: | @@ -86,6 +90,13 @@ jobs: exit 1 fi - uses: actions/checkout@v4.1.1 + - uses: dorny/paths-filter@v3 + id: changes + with: + list-files: 'json' + filters: | + rocks: + - '**/rockcraft.yaml' - name: Generate rock paths and images id: gen-rock-paths-and-images uses: actions/github-script@v7.0.1 @@ -96,69 +107,85 @@ jobs: const workingDir = inputs['working-directory'] const multiarch = inputs['multiarch-awareness'] const rockcraftGlobber = await glob.create( - path.join(workingDir, '**/rockcraft.yaml') + path.join(workingDir, '**/rockcraft.yaml') ) const rockPaths = [] const images = [] const rockMetas = [] + const changedMetas = [] const defaultArch = 'amd64' + const changes = ${{ toJSON(steps.changes) }} + const changesPaths = JSON.parse(changes['outputs']['rocks_files']) const platformLabels = JSON.parse(inputs['platform-labels']) const rockcraftRevisions = JSON.parse(inputs['rockcraft-revisions']) - - core.info(`Multiarch Awareness is ${multiarch ? "on" : "off" }`) + const isPullRequest = ${{ github.event_name == 'pull_request' }} + core.info(`Multiarch Awareness is ${multiarch ? "on" : "off"}`) for (const rockcraftFile of await rockcraftGlobber.glob()) { - const rockPath = path.relative('.', path.dirname(rockcraftFile)) || "./" - core.info(`found rockcraft.yaml in ${rockPath}`) - const fileHash = await glob.hashFiles(path.join(rockPath, '**')) - const [rockName, rockVersion] = ( - await exec.getExecOutput('yq', ['.name,.version', rockcraftFile]) - ).stdout.trim().split("\n") - const platforms = ( - await exec.getExecOutput('yq', ['.platforms | keys', '-o=json', rockcraftFile]) - ).stdout.trim() - if (multiarch && platforms) { - const arches = JSON.parse(platforms) - for (arch of arches) { - const image = `${{ inputs.registry }}/${{ inputs.owner }}/${rockName}:${fileHash}-${arch}` - core.info(`generate multi-arch image name: ${image}`) - images.push(image) - rockMetas.push({ - name: rockName, - version: rockVersion, - path: rockPath, - arch: arch, - image: image, - "rockcraft-revision": rockcraftRevisions[arch] || '', - "runs-on-labels": platformLabels[arch] || [inputs["runs-on"]] - }) + const rockPath = path.relative('.', path.dirname(rockcraftFile)) || "./" + core.info(`found rockcraft.yaml in ${rockPath}`) + const fileHash = await glob.hashFiles(path.join(rockPath, '**')) + const [rockName, rockVersion] = ( + await exec.getExecOutput('yq', ['.name,.version', rockcraftFile]) + ).stdout.trim().split("\n") + const platforms = ( + await exec.getExecOutput('yq', ['.platforms | keys', '-o=json', rockcraftFile]) + ).stdout.trim() + if (multiarch && platforms) { + const arches = JSON.parse(platforms) + for (arch of arches) { + const image = `${{inputs.registry}}/${{inputs.owner}}/${rockName}:${fileHash}-${arch}` + core.info(`generate multi-arch image name: ${image}`) + images.push(image) + let meta = { + name: rockName, + version: rockVersion, + path: rockPath, + arch: arch, + image: image, + "rockcraft-revision": rockcraftRevisions[arch] || '', + "runs-on-labels": platformLabels[arch] || [inputs["runs-on"]] + } + rockMetas.push(meta) + if (isPullRequest && changesPaths.includes(`${rockPath}/rockcraft.yaml`)) { + changedMetas.push(meta) + } else if (!isPullRequest) { + changedMetas.push(meta) + } + } + } else { + const image = `${{inputs.registry}}/${{inputs.owner}}/${rockName}:${fileHash}` + core.info(`generate image name: ${image}`) + images.push(image) + let meta = { + name: rockName, + version: rockVersion, + path: rockPath, + arch: defaultArch, + image: image, + "rockcraft-revision": rockcraftRevisions[defaultArch] || '', + "runs-on-labels": platformLabels[defaultArch] || [inputs["runs-on"]] + }; + rockMetas.push(meta) + if (isPullRequest && changesPaths.includes(`${rockPath}/rockcraft.yaml`)) { + changedMetas.push(meta) + } else if (!isPullRequest) { + changedMetas.push(meta) + } } - } else { - const image = `${{ inputs.registry }}/${{ inputs.owner }}/${rockName}:${fileHash}` - core.info(`generate image name: ${image}`) - images.push(image) - rockMetas.push({ - name: rockName, - version: rockVersion, - path: rockPath, - arch: defaultArch, - image: image, - "rockcraft-revision": rockcraftRevisions[defaultArch] || '', - "runs-on-labels": platformLabels[defaultArch] || [inputs["runs-on"]] - }) - } - rockPaths.push(rockPath) + rockPaths.push(rockPath) } core.setOutput('rock-metas', JSON.stringify(rockMetas)) + core.setOutput('changed-rock-metas', JSON.stringify(changedMetas)) core.setOutput('rock-paths', JSON.stringify(rockPaths)) core.setOutput('images', JSON.stringify(images)) build-rocks: name: Build rock needs: [get-rocks] - if: ${{ needs.get-rocks.outputs.rock-metas != '[]' }} + if: ${{ needs.get-rocks.outputs.changed-rock-metas != '[]' }} strategy: matrix: - rock: ${{ fromJSON(needs.get-rocks.outputs.rock-metas) }} + rock: ${{ fromJSON(needs.get-rocks.outputs.changed-rock-metas) }} fail-fast: false runs-on: ${{ matrix.rock.runs-on-labels }} permissions: