Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/__greetings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ permissions: {}

jobs:
greetings:
uses: hoverkraft-tech/ci-github-common/.github/workflows/greetings.yml@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/.github/workflows/greetings.yml@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
permissions:
contents: read
issues: write
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/__need-fix-to-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ permissions: {}

jobs:
main:
uses: hoverkraft-tech/ci-github-common/.github/workflows/need-fix-to-issue.yml@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/.github/workflows/need-fix-to-issue.yml@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
permissions:
contents: read
issues: write
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/__semantic-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ permissions: {}

jobs:
main:
uses: hoverkraft-tech/ci-github-common/.github/workflows/semantic-pull-request.yml@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/.github/workflows/semantic-pull-request.yml@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
permissions:
contents: write
pull-requests: write
2 changes: 1 addition & 1 deletion .github/workflows/__shared-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ permissions:

jobs:
linter:
uses: hoverkraft-tech/ci-github-common/.github/workflows/linter.yml@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/.github/workflows/linter.yml@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0

test-action-docker-build-image:
needs: linter
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/__stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ permissions: {}

jobs:
main:
uses: hoverkraft-tech/ci-github-common/.github/workflows/stale.yml@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/.github/workflows/stale.yml@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
permissions:
issues: write
pull-requests: write
14 changes: 7 additions & 7 deletions .github/workflows/docker-build-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ jobs:
packages: write
id-token: write # Needed for getting local workflow actions
steps:
- uses: hoverkraft-tech/ci-github-common/actions/checkout@4b53189212d5810f710bed89711002626977215b # 0.33.0
- uses: hoverkraft-tech/ci-github-common/actions/checkout@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
with:
lfs: ${{ inputs.lfs }}

Expand All @@ -381,7 +381,7 @@ jobs:
run: git lfs pull

- id: local-workflow-actions
uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
with:
actions-path: actions

Expand Down Expand Up @@ -452,12 +452,12 @@ jobs:

# FIXME: Set built images infos in file to be uploaded as artifacts, because github action does not handle job outputs for matrix
# https://github.com/orgs/community/discussions/26639
- uses: hoverkraft-tech/ci-github-common/actions/set-matrix-output@4b53189212d5810f710bed89711002626977215b # 0.33.0
- uses: hoverkraft-tech/ci-github-common/actions/set-matrix-output@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
with:
artifact-name: ${{ needs.prepare-variables.outputs.artifact-name }}
value: ${{ steps.build.outputs.built-image }}

- uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@4b53189212d5810f710bed89711002626977215b # 0.33.0
- uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
if: always() && steps.local-workflow-actions.outputs.repository
with:
actions-path: actions
Expand All @@ -476,7 +476,7 @@ jobs:
built-images: ${{ steps.create-images-manifests.outputs.built-images }}
steps:
- id: get-matrix-outputs
uses: hoverkraft-tech/ci-github-common/actions/get-matrix-outputs@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/actions/get-matrix-outputs@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
with:
artifact-name: ${{ needs.prepare-variables.outputs.artifact-name }}

Expand Down Expand Up @@ -514,7 +514,7 @@ jobs:
core.setOutput('built-images', JSON.stringify(images));

- id: local-workflow-actions
uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
with:
actions-path: actions

Expand Down Expand Up @@ -551,7 +551,7 @@ jobs:
images: ${{ steps.get-images-to-sign.outputs.images-to-sign }}
github-token: ${{ secrets.GITHUB_TOKEN }}

- uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@4b53189212d5810f710bed89711002626977215b # 0.33.0
- uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
if: always() && steps.local-workflow-actions.outputs.repository
with:
actions-path: actions
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/prune-pull-requests-images-tags.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ jobs:
id-token: write # Needed for getting local workflow actions
steps:
- id: local-workflow-actions
uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
with:
actions-path: actions

Expand All @@ -118,7 +118,7 @@ jobs:
pull-request-tag-filter: ${{ inputs.pull-request-tag-filter }}
preserve-tags-filter: ${{ inputs.preserve-tags-filter }}

- uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@4b53189212d5810f710bed89711002626977215b # 0.33.0
- uses: hoverkraft-tech/ci-github-common/actions/local-workflow-actions@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
if: always() && steps.local-workflow-actions.outputs.repository
with:
actions-path: actions
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ _Actions that operate on OCI images across their build, metadata, and lifecycle

#### - [Build image](actions/docker/build-image/README.md)

#### - [Cleanup builder](actions/docker/cleanup-builder/README.md)

#### - [Clean images](actions/docker/clean-images/README.md)

#### - [Create images manifests](actions/docker/create-images-manifests/README.md)
Expand Down
42 changes: 30 additions & 12 deletions actions/docker/build-image/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,36 +149,40 @@ outputs:
runs:
using: "composite"
steps:
- shell: bash
# FIXME: workaround until will be merged: https://github.com/actions/runner/pull/1684
run: mkdir -p ./self-actions/ && cp -r $GITHUB_ACTION_PATH/../../* ./self-actions/
- uses: hoverkraft-tech/ci-github-common/actions/local-actions@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
with:
source-path: ${{ github.action_path }}/../..

- id: slugify-platform
uses: hoverkraft-tech/ci-github-common/actions/slugify@4b53189212d5810f710bed89711002626977215b # 0.33.0
uses: hoverkraft-tech/ci-github-common/actions/slugify@a236f015b7dda4712d2ba4d327b8bf27be4c3d3a # 0.34.0
with:
value: ${{ inputs.platform }}

- id: docker-setup
uses: ./self-actions/docker/setup
uses: ./../self-actions/docker/setup
with:
oci-registry: ${{ inputs.oci-registry }}
oci-registry-username: ${{ inputs.oci-registry-username }}
oci-registry-password: ${{ inputs.oci-registry-password }}
buildkitd-config-inline: ${{ inputs.buildkitd-config-inline }}
buildx-cleanup: false

- name: Register Buildx cleanup
# FIXME: Workaround for GitHub Actions post-step ordering behavior with composite actions.
# The built-in Buildx cleanup can run before later post steps that still need the builder.
# See: https://github.com/actions/runner/issues/1657
uses: ./../self-actions/docker/cleanup-builder
with:
builder: ${{ steps.docker-setup.outputs.buildx-name }}

- id: metadata
uses: ./self-actions/docker/get-image-metadata
uses: ./../self-actions/docker/get-image-metadata
with:
oci-registry: ${{ steps.docker-setup.outputs.push-registry }}
repository: ${{ inputs.repository }}
image: ${{ inputs.image }}
tag: ${{ inputs.tag }}

- shell: bash
# FIXME: workaround until will be merged: https://github.com/actions/runner/pull/1684
run: |
rm -fr ./self-actions

- id: get-docker-config
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
Expand All @@ -190,8 +194,10 @@ runs:
MULTI_PLATFORM_INPUT: ${{ inputs.multi-platform }}
PLATFORM_INPUT: ${{ inputs.platform }}
SLUGIFIED_PLATFORM: ${{ steps.slugify-platform.outputs.result }}
TARGET_INPUT: ${{ inputs.target }}
with:
script: |
const { createHash } = require('crypto');
const fs = require('fs');
const path = require('path');

Expand All @@ -210,6 +216,16 @@ runs:
const resolvedDockerfilePath = fs.realpathSync(dockerfilePath);
core.setOutput('dockerfile-path', resolvedDockerfilePath);

const cacheMountScope = JSON.stringify({
image: process.env.METADATA_IMAGE || '',
platform: process.env.PLATFORM_INPUT || '',
target: process.env.TARGET_INPUT || '',
});
const cacheMountScopeHash = createHash('sha256')
.update(cacheMountScope)
.digest('hex');
core.setOutput('cache-mount-scope', cacheMountScopeHash);

const slugifiedPlatform = process.env.SLUGIFIED_PLATFORM || '';
const tagSuffix = `-${slugifiedPlatform}`;
core.setOutput('cache-flavor', `suffix=${tagSuffix}`);
Expand Down Expand Up @@ -299,7 +315,9 @@ runs:
id: cache
with:
path: cache-mount
key: cache-mount-${{ hashFiles(steps.get-docker-config.outputs.dockerfile-path) }}
key: cache-mount-${{ hashFiles(steps.get-docker-config.outputs.dockerfile-path) }}-${{ steps.get-docker-config.outputs.cache-mount-scope }}
restore-keys: |
cache-mount-${{ hashFiles(steps.get-docker-config.outputs.dockerfile-path) }}-

- name: Restore Docker cache mounts
uses: reproducible-containers/buildkit-cache-dance@1b8ab18fbda5ad3646e3fcc9ed9dd41ce2f297b4 # v3.3.2
Expand Down
70 changes: 70 additions & 0 deletions actions/docker/cleanup-builder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!-- header:start -->

# ![Icon](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItdHJhc2gtMiIgY29sb3I9ImJsdWUiPjxwb2x5bGluZSBwb2ludHM9IjMgNiA1IDIwIDIxIDIwIDIxIDYiPjwvcG9seWxpbmU+PHBhdGggZD0iTTE5IDZWNGExIDEgMCAwIDAtMS0xaC00YTEgMSAwIDAgMC0xIDF2Mk01IDZoMTQiPjwvcGF0aD48cGF0aCBkPSJNMTAgMTF2NiI+PC9wYXRoPjxwYXRoIGQ9Ik0xNCAxMXY2Ij48L3BhdGg+PC9zdmc+) GitHub Action: Docker - Cleanup builder

<div align="center">
<img src="../../../.github/logo.svg" width="60px" align="center" alt="Docker - Cleanup builder" />
</div>

---

<!-- header:end -->
<!-- overview:start -->

## Overview

Registers a post-job step that removes a Docker Buildx builder after later post-job hooks have finished.
This action exists as a workaround for GitHub Actions post-step ordering behavior with composite actions, where the effective cleanup order may not match the visible reverse order of YAML steps.

<!-- overview:end -->
<!-- usage:start -->

## Usage

```yaml
- uses: hoverkraft-tech/ci-github-container/actions/docker/cleanup-builder@main
with:
builder: ${{ steps.docker-setup.outputs.buildx-name }}
enabled: true
```

<!-- usage:end -->
<!-- inputs:start -->

## Inputs

| **Input** | **Description** | **Required** | **Default** |
| ------------- | ------------------------------------------------------------- | ------------ | ----------- |
| **`builder`** | Docker Buildx builder name to remove during post-job cleanup. | **false** | - |
| **`enabled`** | Whether cleanup should run during the post-job phase. | **false** | `true` |

<!-- inputs:end -->

## Notes

Use this action before other actions whose post-job hooks still need the builder. It is intended as a workaround for GitHub Actions runner behavior around post-step ordering in composite actions. See [actions/runner#1657](https://github.com/actions/runner/issues/1657).

In practice, this means the built-in `docker/setup-buildx-action` cleanup can run too early for actions such as `docker/build-push-action` or `reproducible-containers/buildkit-cache-dance` that still access the builder during their own post-job hooks.

This action works by registering its cleanup post hook earlier, so the runner executes it later than the post hooks that still need the builder.

<!-- contributing:start -->

## Contributing

Contributions are welcome! Please see the [contributing guidelines](https://github.com/hoverkraft-tech/ci-github-container/blob/main/CONTRIBUTING.md) for more details.

<!-- contributing:end -->
<!-- license:start -->

## License

This project is licensed under the MIT License.

SPDX-License-Identifier: MIT

Copyright © 2026 hoverkraft

For more details, see the [license](http://choosealicense.com/licenses/mit/).

<!-- license:end -->
22 changes: 22 additions & 0 deletions actions/docker/cleanup-builder/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: "Docker - Cleanup builder"
description: |
Register a post-job step that removes a Docker Buildx builder after later post steps have finished.
author: hoverkraft
branding:
icon: trash-2
color: blue

inputs:
builder:
description: "Docker Buildx builder name to remove during post-job cleanup."
required: false
enabled:
description: "Whether cleanup should run during the post-job phase."
default: true
required: false

runs:
using: "node24"
main: "index.js"
post: "post.js"
post-if: "always()"
17 changes: 17 additions & 0 deletions actions/docker/cleanup-builder/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const fs = require("fs");

function appendState(name, value) {
const stateFile = process.env.GITHUB_STATE;
if (!stateFile) {
return;
}

fs.appendFileSync(stateFile, `${name}=${value}\n`, { encoding: "utf8" });
}

const enabled =
(process.env.INPUT_ENABLED || "true").trim().toLowerCase() !== "false";
const builder = (process.env.INPUT_BUILDER || "").trim();

appendState("enabled", String(enabled));
appendState("builder", builder);
56 changes: 56 additions & 0 deletions actions/docker/cleanup-builder/post.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const { spawnSync } = require("child_process");

function info(message) {
process.stdout.write(`${message}\n`);
}

function warning(message) {
process.stdout.write(`::warning::${message}\n`);
}

function commandExists(command) {
const result = spawnSync(command, ["--version"], { stdio: "ignore" });
return result.status === 0;
}

function builderExists(builder) {
const result = spawnSync("docker", ["buildx", "inspect", builder], {
stdio: "ignore",
});
return result.status === 0;
}

const enabled =
(process.env.STATE_enabled || "true").trim().toLowerCase() !== "false";
const builder = (process.env.STATE_builder || "").trim();

if (!enabled) {
info("Buildx cleanup disabled. Skipping builder cleanup.");
process.exit(0);
}

if (!builder) {
info("No Buildx builder configured for cleanup.");
process.exit(0);
}

if (!commandExists("docker")) {
warning(
"Docker CLI is unavailable during builder cleanup. Skipping cleanup.",
);
process.exit(0);
}

if (!builderExists(builder)) {
info(`Buildx builder "${builder}" is already absent. Skipping cleanup.`);
process.exit(0);
}

info(`Removing Buildx builder "${builder}".`);
const removeResult = spawnSync("docker", ["buildx", "rm", builder], {
stdio: "inherit",
});

if (removeResult.status !== 0) {
warning(`Failed to remove Buildx builder "${builder}".`);
}
Loading
Loading