diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3afdbd1..da51171 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -549,3 +549,33 @@ jobs: cwd://${{ steps.docker_meta.outputs.bake-file-labels }} targets: | release + + sha-short: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + short-length: + - '' + - 16 + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + version: ${{ env.BUILDX_VERSION }} + driver: docker + - + name: Docker meta + uses: ./ + with: + images: | + ${{ env.DOCKER_IMAGE }} + ghcr.io/name/app + tags: | + type=sha + env: + DOCKER_METADATA_SHORT_SHA_LENGTH: ${{ matrix.short-length }} diff --git a/README.md b/README.md index 1ed98cd..2bf7eb8 100644 --- a/README.md +++ b/README.md @@ -360,10 +360,11 @@ So it can be used with our [Docker Build Push action](https://github.com/docker/ ### environment variables -| Name | Type | Description | -|--------------------------------------|--------|------------------------------------------------------------------------------------------------------------| -| `DOCKER_METADATA_PR_HEAD_SHA` | Bool | If `true`, set associated head SHA instead of commit SHA that triggered the workflow on pull request event | -| `DOCKER_METADATA_ANNOTATIONS_LEVELS` | String | Comma separated list of annotations levels to set for annotations output separated (default `manifest`) | +| Name | Type | Description | +|--------------------------------------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------| +| `DOCKER_METADATA_PR_HEAD_SHA` | Bool | If `true`, set associated head SHA instead of commit SHA that triggered the workflow on pull request event | +| `DOCKER_METADATA_SHORT_SHA_LENGTH` | Number | Specifies the length of the [short commit SHA](#typesha) to ensure uniqueness. Default is `12`, but can be increased for larger repositories. | +| `DOCKER_METADATA_ANNOTATIONS_LEVELS` | String | Comma separated list of annotations levels to set for annotations output separated (default `manifest`) | ## `context` input @@ -725,6 +726,24 @@ tags: | Output Git short commit (or long if specified) as Docker tag like `sha-860c1904a1ce`. +By default, the length of the short commit SHA is `12` characters. You can +increase this length for larger repositories by setting the +[`DOCKER_METADATA_SHORT_SHA_LENGTH` environment variable](#environment-variables): + +```yaml + - + name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + name/app + tags: | + type=sha + env: + DOCKER_METADATA_SHORT_SHA_LENGTH: 16 +``` + Extended attributes and default values: ```yaml diff --git a/src/meta.ts b/src/meta.ts index d80fa31..e45af49 100644 --- a/src/meta.ts +++ b/src/meta.ts @@ -14,6 +14,8 @@ import * as icl from './image'; import * as tcl from './tag'; import * as fcl from './flavor'; +const defaultShortShaLength = 12; + export interface Version { main: string | undefined; partial: string[]; @@ -307,7 +309,7 @@ export class Meta { let val = this.context.sha; if (tag.attrs['format'] === tcl.ShaFormat.Short) { - val = this.context.sha.substring(0, 12); + val = Meta.shortSha(this.context.sha); } const vraw = this.setValue(val, tag); @@ -373,7 +375,7 @@ export class Meta { return context.ref.replace(/^refs\/tags\//g, ''); }, sha: function () { - return context.sha.substring(0, 12); + return Meta.shortSha(context.sha); }, base_ref: function () { if (/^refs\/tags\//.test(context.ref) && context.payload?.base_ref != undefined) { @@ -593,4 +595,18 @@ export class Meta { private static sanitizeTag(tag: string): string { return tag.replace(/[^a-zA-Z0-9._-]+/g, '-'); } + + private static shortSha(sha: string): string { + let shortShaLength = defaultShortShaLength; + if (process.env.DOCKER_METADATA_SHORT_SHA_LENGTH) { + if (isNaN(Number(process.env.DOCKER_METADATA_SHORT_SHA_LENGTH))) { + throw new Error(`DOCKER_METADATA_SHORT_SHA_LENGTH is not a valid number: ${process.env.DOCKER_METADATA_SHORT_SHA_LENGTH}`); + } + shortShaLength = Number(process.env.DOCKER_METADATA_SHORT_SHA_LENGTH); + } + if (shortShaLength >= sha.length) { + return sha; + } + return sha.substring(0, shortShaLength); + } }