Compare commits
No commits in common. "master" and "v5.2.0" have entirely different histories.
|
@ -1,12 +1,2 @@
|
||||||
/coverage
|
/coverage
|
||||||
|
/node_modules
|
||||||
# Dependency directories
|
|
||||||
node_modules/
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# yarn v2
|
|
||||||
.yarn/cache
|
|
||||||
.yarn/unplugged
|
|
||||||
.yarn/build-state.yml
|
|
||||||
.yarn/install-state.gz
|
|
||||||
.pnp.*
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
],
|
],
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2023,
|
"ecmaVersion": "latest",
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
/.yarn/releases/** binary
|
|
||||||
/.yarn/plugins/** binary
|
|
||||||
/__tests__/fixtures/** -linguist-detectable
|
/__tests__/fixtures/** -linguist-detectable
|
||||||
/dist/** linguist-generated=true
|
/dist/** linguist-generated=true
|
||||||
/lib/** linguist-generated=true
|
/lib/** linguist-generated=true
|
||||||
|
|
|
@ -17,39 +17,14 @@ on:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DOCKER_IMAGE: localhost:5000/name/app
|
DOCKER_IMAGE: localhost:5000/name/app
|
||||||
BUILDX_VERSION: latest
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
context:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
context:
|
|
||||||
- workflow
|
|
||||||
- git
|
|
||||||
steps:
|
|
||||||
-
|
|
||||||
name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
-
|
|
||||||
name: Docker meta
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
context: ${{ matrix.context }}
|
|
||||||
|
|
||||||
multi-images:
|
multi-images:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
uses: ./
|
uses: ./
|
||||||
|
@ -81,12 +56,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
uses: ./
|
uses: ./
|
||||||
|
@ -117,12 +86,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
uses: ./
|
uses: ./
|
||||||
|
@ -151,12 +114,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
uses: ./
|
uses: ./
|
||||||
|
@ -182,12 +139,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
uses: ./
|
uses: ./
|
||||||
|
@ -205,12 +156,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
uses: ./
|
uses: ./
|
||||||
|
@ -226,12 +171,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
uses: ./
|
uses: ./
|
||||||
|
@ -256,12 +195,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
uses: ./
|
uses: ./
|
||||||
|
@ -269,8 +202,6 @@ jobs:
|
||||||
images: |
|
images: |
|
||||||
${{ env.DOCKER_IMAGE }}
|
${{ env.DOCKER_IMAGE }}
|
||||||
ghcr.io/name/app
|
ghcr.io/name/app
|
||||||
labels: |
|
|
||||||
org.opencontainers.image.created={{commit_date 'YYYY-MM-DDTHH:mm:ss.SSS[Z]'}}
|
|
||||||
tags: |
|
tags: |
|
||||||
type=sha
|
type=sha
|
||||||
type=raw,value=gexp-branch-{{branch}}
|
type=raw,value=gexp-branch-{{branch}}
|
||||||
|
@ -285,12 +216,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
|
@ -320,12 +245,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
-
|
|
||||||
name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
with:
|
|
||||||
version: ${{ env.BUILDX_VERSION }}
|
|
||||||
driver-opts: network=host
|
|
||||||
-
|
-
|
||||||
name: Docker meta
|
name: Docker meta
|
||||||
id: docker_meta
|
id: docker_meta
|
||||||
|
@ -342,9 +261,17 @@ jobs:
|
||||||
type=semver,pattern=v{{major}}.{{minor}}
|
type=semver,pattern=v{{major}}.{{minor}}
|
||||||
type=semver,pattern=v{{major}}
|
type=semver,pattern=v{{major}}
|
||||||
type=sha
|
type=sha
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
driver-opts: network=host
|
||||||
-
|
-
|
||||||
name: Build and push to local registry
|
name: Build and push to local registry
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: ./test
|
context: ./test
|
||||||
file: ./test/Dockerfile
|
file: ./test/Dockerfile
|
||||||
|
@ -361,6 +288,10 @@ jobs:
|
||||||
name: Check manifest
|
name: Check manifest
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.docker_meta.outputs.version }}
|
docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.docker_meta.outputs.version }}
|
||||||
|
-
|
||||||
|
name: Dump context
|
||||||
|
if: always()
|
||||||
|
uses: crazy-max/ghaction-dump-context@v2
|
||||||
|
|
||||||
bake:
|
bake:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -368,11 +299,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
-
|
|
||||||
name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
with:
|
|
||||||
version: ${{ env.BUILDX_VERSION }}
|
|
||||||
-
|
-
|
||||||
name: Docker meta
|
name: Docker meta
|
||||||
id: docker_meta
|
id: docker_meta
|
||||||
|
@ -390,14 +316,20 @@ jobs:
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
type=sha
|
type=sha
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
-
|
-
|
||||||
name: Build
|
name: Build
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@v4
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
./test/docker-bake.hcl
|
./test/docker-bake.hcl
|
||||||
cwd://${{ steps.docker_meta.outputs.bake-file-tags }}
|
${{ steps.docker_meta.outputs.bake-file-tags }}
|
||||||
cwd://${{ steps.docker_meta.outputs.bake-file-labels }}
|
${{ steps.docker_meta.outputs.bake-file-labels }}
|
||||||
targets: |
|
targets: |
|
||||||
release
|
release
|
||||||
|
|
||||||
|
@ -413,12 +345,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
|
@ -441,12 +367,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
|
@ -461,7 +381,7 @@ jobs:
|
||||||
maintainer=Foo
|
maintainer=Foo
|
||||||
-
|
-
|
||||||
name: Build
|
name: Build
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: ./test
|
context: ./test
|
||||||
file: ./test/output.Dockerfile
|
file: ./test/output.Dockerfile
|
||||||
|
@ -472,43 +392,12 @@ jobs:
|
||||||
DOCKER_METADATA_OUTPUT_ANNOTATIONS
|
DOCKER_METADATA_OUTPUT_ANNOTATIONS
|
||||||
DOCKER_METADATA_OUTPUT_JSON
|
DOCKER_METADATA_OUTPUT_JSON
|
||||||
|
|
||||||
no-output-env:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
DOCKER_METADATA_SET_OUTPUT_ENV: false
|
|
||||||
steps:
|
|
||||||
-
|
|
||||||
name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
-
|
|
||||||
name: Docker meta
|
|
||||||
id: meta
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
images: |
|
|
||||||
${{ env.DOCKER_IMAGE }}
|
|
||||||
ghcr.io/name/app
|
|
||||||
labels: |
|
|
||||||
maintainer=CrazyMax
|
|
||||||
annotations: |
|
|
||||||
maintainer=Foo
|
|
||||||
-
|
|
||||||
name: No output environment variables set
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
[[ "$(printenv | grep "^DOCKER_METADATA_OUTPUT_" | wc -l)" -eq 0 ]] || exit 1
|
|
||||||
|
|
||||||
bake-annotations:
|
bake-annotations:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
-
|
|
||||||
name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
with:
|
|
||||||
version: ${{ env.BUILDX_VERSION }}
|
|
||||||
-
|
-
|
||||||
name: Docker meta
|
name: Docker meta
|
||||||
id: docker_meta
|
id: docker_meta
|
||||||
|
@ -528,14 +417,22 @@ jobs:
|
||||||
type=sha
|
type=sha
|
||||||
env:
|
env:
|
||||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
version: v0.12.0-rc1
|
||||||
-
|
-
|
||||||
name: Build
|
name: Build
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@v4
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
./test/docker-bake.hcl
|
./test/docker-bake.hcl
|
||||||
cwd://${{ steps.docker_meta.outputs.bake-file-tags }}
|
${{ steps.docker_meta.outputs.bake-file-tags }}
|
||||||
cwd://${{ steps.docker_meta.outputs.bake-file-annotations }}
|
${{ steps.docker_meta.outputs.bake-file-annotations }}
|
||||||
targets: |
|
targets: |
|
||||||
release
|
release
|
||||||
|
|
||||||
|
@ -545,12 +442,6 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
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
|
name: Docker meta
|
||||||
uses: ./
|
uses: ./
|
||||||
|
@ -564,70 +455,3 @@ jobs:
|
||||||
-
|
-
|
||||||
name: Print envs
|
name: Print envs
|
||||||
run: env|sort
|
run: env|sort
|
||||||
|
|
||||||
bake-path-context:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
-
|
|
||||||
name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
-
|
|
||||||
name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
with:
|
|
||||||
version: latest
|
|
||||||
-
|
|
||||||
name: Docker meta
|
|
||||||
id: docker_meta
|
|
||||||
uses: ./
|
|
||||||
-
|
|
||||||
name: Build
|
|
||||||
uses: docker/bake-action@v6
|
|
||||||
with:
|
|
||||||
source: .
|
|
||||||
files: |
|
|
||||||
./test/docker-bake.hcl
|
|
||||||
${{ steps.docker_meta.outputs.bake-file-tags }}
|
|
||||||
${{ 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 }}
|
|
||||||
|
|
||||||
dump:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
-
|
|
||||||
name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
-
|
|
||||||
name: Dump context
|
|
||||||
uses: crazy-max/ghaction-dump-context@v2
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
name: publish
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- published
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
id-token: write
|
|
||||||
packages: write
|
|
||||||
steps:
|
|
||||||
-
|
|
||||||
name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
-
|
|
||||||
name: Publish
|
|
||||||
uses: actions/publish-immutable-action@v0.0.4
|
|
|
@ -15,14 +15,16 @@ jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
-
|
-
|
||||||
name: Test
|
name: Test
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@v4
|
||||||
with:
|
with:
|
||||||
targets: test
|
targets: test
|
||||||
-
|
-
|
||||||
name: Upload coverage
|
name: Upload coverage
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
file: ./coverage/clover.xml
|
file: ./coverage/clover.xml
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
|
|
|
@ -15,17 +15,16 @@ jobs:
|
||||||
prepare:
|
prepare:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
targets: ${{ steps.generate.outputs.targets }}
|
targets: ${{ steps.targets.outputs.matrix }}
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
-
|
-
|
||||||
name: List targets
|
name: Targets matrix
|
||||||
id: generate
|
id: targets
|
||||||
uses: docker/bake-action/subaction/list-targets@v6
|
run: |
|
||||||
with:
|
echo "matrix=$(docker buildx bake validate --print | jq -cr '.group.validate.targets')" >> $GITHUB_OUTPUT
|
||||||
target: validate
|
|
||||||
|
|
||||||
validate:
|
validate:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -36,8 +35,11 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
target: ${{ fromJson(needs.prepare.outputs.targets) }}
|
target: ${{ fromJson(needs.prepare.outputs.targets) }}
|
||||||
steps:
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
-
|
-
|
||||||
name: Validate
|
name: Validate
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@v4
|
||||||
with:
|
with:
|
||||||
targets: ${{ matrix.target }}
|
targets: ${{ matrix.target }}
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
# https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
/.dev
|
||||||
|
node_modules/
|
||||||
|
lib
|
||||||
|
|
||||||
|
# Jetbrains
|
||||||
|
/.idea
|
||||||
|
/*.iml
|
||||||
|
|
||||||
|
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
@ -7,7 +14,6 @@ npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
lerna-debug.log*
|
lerna-debug.log*
|
||||||
.pnpm-debug.log*
|
|
||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
@ -18,14 +24,34 @@ pids
|
||||||
*.seed
|
*.seed
|
||||||
*.pid.lock
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
# Coverage directory used by tools like istanbul
|
||||||
coverage
|
coverage
|
||||||
*.lcov
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
# Dependency directories
|
# Dependency directories
|
||||||
node_modules/
|
|
||||||
jspm_packages/
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
# TypeScript cache
|
# TypeScript cache
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
@ -35,19 +61,36 @@ jspm_packages/
|
||||||
# Optional eslint cache
|
# Optional eslint cache
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
# Yarn Integrity file
|
# Yarn Integrity file
|
||||||
.yarn-integrity
|
.yarn-integrity
|
||||||
|
|
||||||
# dotenv environment variable files
|
# dotenv environment variables file
|
||||||
.env
|
.env
|
||||||
.env.development.local
|
.env.test
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
.env.local
|
|
||||||
|
|
||||||
# yarn v2
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
.yarn/cache
|
.cache
|
||||||
.yarn/unplugged
|
|
||||||
.yarn/build-state.yml
|
# next.js build output
|
||||||
.yarn/install-state.gz
|
.next
|
||||||
.pnp.*
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
# Dependency directories
|
|
||||||
node_modules/
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# yarn v2
|
|
||||||
.yarn/
|
|
File diff suppressed because one or more lines are too long
13
.yarnrc.yml
13
.yarnrc.yml
|
@ -1,13 +0,0 @@
|
||||||
logFilters:
|
|
||||||
- code: YN0013
|
|
||||||
level: discard
|
|
||||||
- code: YN0019
|
|
||||||
level: discard
|
|
||||||
- code: YN0076
|
|
||||||
level: discard
|
|
||||||
|
|
||||||
nodeLinker: node-modules
|
|
||||||
|
|
||||||
plugins:
|
|
||||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
|
||||||
spec: "@yarnpkg/plugin-interactive-tools"
|
|
92
README.md
92
README.md
|
@ -45,7 +45,6 @@ ___
|
||||||
* [`{{base_ref}}`](#base_ref)
|
* [`{{base_ref}}`](#base_ref)
|
||||||
* [`{{is_default_branch}}`](#is_default_branch)
|
* [`{{is_default_branch}}`](#is_default_branch)
|
||||||
* [`{{date '<format>' tz='<timezone>'}}`](#date-format-tztimezone)
|
* [`{{date '<format>' tz='<timezone>'}}`](#date-format-tztimezone)
|
||||||
* [`{{commit_date '<format>' tz='<timezone>'}}`](#commit_date-format-tztimezone)
|
|
||||||
* [Major version zero](#major-version-zero)
|
* [Major version zero](#major-version-zero)
|
||||||
* [JSON output object](#json-output-object)
|
* [JSON output object](#json-output-object)
|
||||||
* [Overwrite labels and annotations](#overwrite-labels-and-annotations)
|
* [Overwrite labels and annotations](#overwrite-labels-and-annotations)
|
||||||
|
@ -92,7 +91,7 @@ jobs:
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
@ -152,7 +151,7 @@ jobs:
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
@ -206,6 +205,9 @@ jobs:
|
||||||
docker:
|
docker:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
-
|
-
|
||||||
name: Docker meta
|
name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
|
@ -221,11 +223,11 @@ jobs:
|
||||||
type=sha
|
type=sha
|
||||||
-
|
-
|
||||||
name: Build
|
name: Build
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@v3
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
./docker-bake.hcl
|
./docker-bake.hcl
|
||||||
cwd://${{ steps.meta.outputs.bake-file }}
|
${{ steps.meta.outputs.bake-file }}
|
||||||
targets: build
|
targets: build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -268,12 +270,12 @@ similar to the previous one:
|
||||||
```yaml
|
```yaml
|
||||||
-
|
-
|
||||||
name: Build
|
name: Build
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@v3
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
./docker-bake.hcl
|
./docker-bake.hcl
|
||||||
cwd://${{ steps.meta.outputs.bake-file-tags }}
|
${{ steps.meta.outputs.bake-file-tags }}
|
||||||
cwd://${{ steps.meta.outputs.bake-file-labels }}
|
${{ steps.meta.outputs.bake-file-labels }}
|
||||||
targets: build
|
targets: build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -298,7 +300,7 @@ The following inputs can be used as `step.with` keys:
|
||||||
| `tags` | List | List of [tags](#tags-input) as key-value pair attributes |
|
| `tags` | List | List of [tags](#tags-input) as key-value pair attributes |
|
||||||
| `flavor` | List | [Flavor](#flavor-input) to apply |
|
| `flavor` | List | [Flavor](#flavor-input) to apply |
|
||||||
| `labels` | List | List of custom labels |
|
| `labels` | List | List of custom labels |
|
||||||
| `annotations` | List | List of custom annotations |
|
| `annotations` | List | List of custom anntoations |
|
||||||
| `sep-tags` | String | Separator to use for tags output (default `\n`) |
|
| `sep-tags` | String | Separator to use for tags output (default `\n`) |
|
||||||
| `sep-labels` | String | Separator to use for labels output (default `\n`) |
|
| `sep-labels` | String | Separator to use for labels output (default `\n`) |
|
||||||
| `sep-annotations` | String | Separator to use for annotations output (default `\n`) |
|
| `sep-annotations` | String | Separator to use for annotations output (default `\n`) |
|
||||||
|
@ -319,7 +321,7 @@ The following outputs are available:
|
||||||
| `bake-file-labels` | File | [Bake file definition](https://docs.docker.com/build/bake/reference/) path with labels |
|
| `bake-file-labels` | File | [Bake file definition](https://docs.docker.com/build/bake/reference/) path with labels |
|
||||||
| `bake-file-annotations` | File | [Bake file definition](https://docs.docker.com/build/bake/reference/) path with [annotations](https://github.com/moby/buildkit/blob/master/docs/annotations.md) |
|
| `bake-file-annotations` | File | [Bake file definition](https://docs.docker.com/build/bake/reference/) path with [annotations](https://github.com/moby/buildkit/blob/master/docs/annotations.md) |
|
||||||
|
|
||||||
Alternatively, each output is also exported as an environment variable when `DOCKER_METADATA_SET_OUTPUT_ENV` is `true`:
|
Alternatively, each output is also exported as an environment variable:
|
||||||
|
|
||||||
* `DOCKER_METADATA_OUTPUT_VERSION`
|
* `DOCKER_METADATA_OUTPUT_VERSION`
|
||||||
* `DOCKER_METADATA_OUTPUT_TAGS`
|
* `DOCKER_METADATA_OUTPUT_TAGS`
|
||||||
|
@ -333,7 +335,7 @@ Alternatively, each output is also exported as an environment variable when `DOC
|
||||||
So it can be used with our [Docker Build Push action](https://github.com/docker/build-push-action/):
|
So it can be used with our [Docker Build Push action](https://github.com/docker/build-push-action/):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: docker/build-push-action@v6
|
- uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
build-args: |
|
build-args: |
|
||||||
DOCKER_METADATA_OUTPUT_JSON
|
DOCKER_METADATA_OUTPUT_JSON
|
||||||
|
@ -341,12 +343,10 @@ So it can be used with our [Docker Build Push action](https://github.com/docker/
|
||||||
|
|
||||||
### environment variables
|
### environment variables
|
||||||
|
|
||||||
| Name | Type | Description |
|
| 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_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 `7`, 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`) |
|
||||||
| `DOCKER_METADATA_ANNOTATIONS_LEVELS` | String | Comma separated list of annotations levels to set for annotations output separated (default `manifest`) |
|
|
||||||
| `DOCKER_METADATA_SET_OUTPUT_ENV` | Bool | If `true`, sets each output as an environment variable (default `true`) |
|
|
||||||
|
|
||||||
## `context` input
|
## `context` input
|
||||||
|
|
||||||
|
@ -705,26 +705,7 @@ tags: |
|
||||||
type=sha,format=long
|
type=sha,format=long
|
||||||
```
|
```
|
||||||
|
|
||||||
Output Git short commit (or long if specified) as Docker tag like
|
Output Git short commit (or long if specified) as Docker tag like `sha-ad132f5`.
|
||||||
`sha-860c190`.
|
|
||||||
|
|
||||||
By default, the length of the short commit SHA is `7` 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: 12
|
|
||||||
```
|
|
||||||
|
|
||||||
Extended attributes and default values:
|
Extended attributes and default values:
|
||||||
|
|
||||||
|
@ -758,7 +739,6 @@ generated by default (`auto` mode) for:
|
||||||
|
|
||||||
* [`type=ref,event=tag`](#typeref)
|
* [`type=ref,event=tag`](#typeref)
|
||||||
* [`type=semver,pattern=...`](#typesemver)
|
* [`type=semver,pattern=...`](#typesemver)
|
||||||
* [`type=pep440,pattern=...`](#typepep440)
|
|
||||||
* [`type=match,pattern=...`](#typematch)
|
* [`type=match,pattern=...`](#typematch)
|
||||||
|
|
||||||
For conditionally tagging with latest for a specific branch name, e.g. if your
|
For conditionally tagging with latest for a specific branch name, e.g. if your
|
||||||
|
@ -800,8 +780,7 @@ Each tags `type` attribute has a default priority:
|
||||||
### Global expressions
|
### Global expressions
|
||||||
|
|
||||||
The following [Handlebars' template](https://handlebarsjs.com/guide/) expressions
|
The following [Handlebars' template](https://handlebarsjs.com/guide/) expressions
|
||||||
for `prefix`, `suffix`, `value` and `enable` attributes of `tags` input are
|
for `prefix`, `suffix`, `value` and `enable` attributes are available:
|
||||||
available:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
tags: |
|
tags: |
|
||||||
|
@ -811,13 +790,6 @@ tags: |
|
||||||
type=raw,value=mytag-{{branch}}-{{sha}}
|
type=raw,value=mytag-{{branch}}-{{sha}}
|
||||||
```
|
```
|
||||||
|
|
||||||
They can also be applied to `labels` and `annotations` inputs:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
labels: |
|
|
||||||
org.opencontainers.image.created={{commit_date 'YYYY-MM-DDTHH:mm:ss.SSS[Z]'}}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `{{branch}}`
|
#### `{{branch}}`
|
||||||
|
|
||||||
Returns the branch name that triggered the workflow run. Will be empty if not
|
Returns the branch name that triggered the workflow run. Will be empty if not
|
||||||
|
@ -880,20 +852,6 @@ Default `tz` is UTC.
|
||||||
| `{{date 'dddd, MMMM Do YYYY, h:mm:ss a'}}` | `Friday, January 10th 2020, 3:25:50 pm` |
|
| `{{date 'dddd, MMMM Do YYYY, h:mm:ss a'}}` | `Friday, January 10th 2020, 3:25:50 pm` |
|
||||||
| `{{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}` | `20200110-093000` |
|
| `{{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}` | `20200110-093000` |
|
||||||
|
|
||||||
#### `{{commit_date '<format>' tz='<timezone>'}}`
|
|
||||||
|
|
||||||
Returns the date when the current git commit is committed, rendered by its
|
|
||||||
[moment format](https://momentjs.com/docs/#/displaying/format/). It falls back
|
|
||||||
to the current date if the commit date is not available.
|
|
||||||
|
|
||||||
Default `tz` is UTC.
|
|
||||||
|
|
||||||
| Expression | Output example |
|
|
||||||
|-----------------------------------------------------|-----------------------------------------|
|
|
||||||
| `{{commit_date 'YYYYMMDD'}}` | `20200110` |
|
|
||||||
| `{{commit_date 'dddd, MMMM Do YYYY, h:mm:ss a'}}` | `Friday, January 10th 2020, 3:25:50 pm` |
|
|
||||||
| `{{commit_date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}` | `20200110-093000` |
|
|
||||||
|
|
||||||
### Major version zero
|
### Major version zero
|
||||||
|
|
||||||
Major version zero (`0.y.z`) is for initial development and **may** change at
|
Major version zero (`0.y.z`) is for initial development and **may** change at
|
||||||
|
@ -927,7 +885,7 @@ that you can reuse them further in your workflow using the [`fromJSON` function]
|
||||||
images: name/app
|
images: name/app
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
@ -974,7 +932,7 @@ of the `metadata-action`:
|
||||||
images: name/app
|
images: name/app
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
annotations: ${{ steps.meta.outputs.annotations }}
|
annotations: ${{ steps.meta.outputs.annotations }}
|
||||||
|
@ -990,12 +948,12 @@ The same can be done with the [`bake-action`](https://github.com/docker/bake-act
|
||||||
images: name/app
|
images: name/app
|
||||||
-
|
-
|
||||||
name: Build
|
name: Build
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@v3
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
./docker-bake.hcl
|
./docker-bake.hcl
|
||||||
cwd://${{ steps.meta.outputs.bake-file-tags }}
|
${{ steps.meta.outputs.bake-file-tags }}
|
||||||
cwd://${{ steps.meta.outputs.bake-file-annotations }}
|
${{ steps.meta.outputs.bake-file-annotations }}
|
||||||
targets: build
|
targets: build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1021,7 +979,7 @@ Please consult the documentation of your registry.
|
||||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
annotations: ${{ steps.meta.outputs.annotations }}
|
annotations: ${{ steps.meta.outputs.annotations }}
|
||||||
|
|
|
@ -0,0 +1,300 @@
|
||||||
|
# Upgrade notes
|
||||||
|
|
||||||
|
## v2 to v3
|
||||||
|
|
||||||
|
* Repository has been moved to docker org. Replace `crazy-max/ghaction-docker-meta@v2`
|
||||||
|
with `docker/metadata-action@v5`
|
||||||
|
* The default bake target has been changed: `ghaction-docker-meta` > `docker-metadata-action`
|
||||||
|
|
||||||
|
## v1 to v2
|
||||||
|
|
||||||
|
* [inputs](#inputs)
|
||||||
|
* [`tag-sha`](#tag-sha)
|
||||||
|
* [`tag-edge` / `tag-edge-branch`](#tag-edge--tag-edge-branch)
|
||||||
|
* [`tag-semver`](#tag-semver)
|
||||||
|
* [`tag-match` / `tag-match-group`](#tag-match--tag-match-group)
|
||||||
|
* [`tag-latest`](#tag-latest)
|
||||||
|
* [`tag-schedule`](#tag-schedule)
|
||||||
|
* [`tag-custom` / `tag-custom-only`](#tag-custom--tag-custom-only)
|
||||||
|
* [`label-custom`](#label-custom)
|
||||||
|
* [Basic workflow](#basic-workflow)
|
||||||
|
* [Semver workflow](#semver-workflow)
|
||||||
|
|
||||||
|
### inputs
|
||||||
|
|
||||||
|
| New | Unchanged | Removed |
|
||||||
|
|------------|-----------------|--------------------|
|
||||||
|
| `tags` | `images` | `tag-sha` |
|
||||||
|
| `flavor` | `sep-tags` | `tag-edge` |
|
||||||
|
| `labels` | `sep-labels` | `tag-edge-branch` |
|
||||||
|
| | | `tag-semver` |
|
||||||
|
| | | `tag-match` |
|
||||||
|
| | | `tag-match-group` |
|
||||||
|
| | | `tag-latest` |
|
||||||
|
| | | `tag-schedule` |
|
||||||
|
| | | `tag-custom` |
|
||||||
|
| | | `tag-custom-only` |
|
||||||
|
| | | `label-custom` |
|
||||||
|
|
||||||
|
#### `tag-sha`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
tags: |
|
||||||
|
type=sha
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `tag-edge` / `tag-edge-branch`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
tags: |
|
||||||
|
# default branch
|
||||||
|
type=edge
|
||||||
|
# specify branch
|
||||||
|
type=edge,branch=main
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `tag-semver`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
tags: |
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `tag-match` / `tag-match-group`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
tags: |
|
||||||
|
type=match,pattern=v(.*),group=1
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `tag-latest`
|
||||||
|
|
||||||
|
`tag-latest` is now handled through the [`flavor` input](README.md#flavor-input):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
flavor: |
|
||||||
|
latest=auto
|
||||||
|
```
|
||||||
|
|
||||||
|
See also the notes about ["latest tag" behavior](README.md#latest-tag)
|
||||||
|
|
||||||
|
#### `tag-schedule`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
tags: |
|
||||||
|
# default tag (nightly)
|
||||||
|
type=schedule
|
||||||
|
# specific pattern
|
||||||
|
type=schedule,pattern={{date 'YYYYMMDD'}}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `tag-custom` / `tag-custom-only`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
tags: |
|
||||||
|
type=raw,value=foo
|
||||||
|
type=raw,value=bar
|
||||||
|
# or
|
||||||
|
type=raw,foo
|
||||||
|
type=raw,bar
|
||||||
|
# or
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `label-custom`
|
||||||
|
|
||||||
|
Same behavior for `labels`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
labels: |
|
||||||
|
maintainer=CrazyMax
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic workflow
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# v1
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v1
|
||||||
|
with:
|
||||||
|
images: name/app
|
||||||
|
-
|
||||||
|
name: Login to DockerHub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# v2
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: name/app
|
||||||
|
-
|
||||||
|
name: Login to DockerHub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Semver workflow
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# v1
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v1
|
||||||
|
with:
|
||||||
|
images: name/app
|
||||||
|
tag-semver: |
|
||||||
|
{{version}}
|
||||||
|
{{major}}.{{minor}}
|
||||||
|
-
|
||||||
|
name: Login to DockerHub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# v2
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: name/app
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=pr
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
-
|
||||||
|
name: Login to DockerHub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
```
|
|
@ -204,20 +204,4 @@ export const context = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getOctokit = jest.fn(() => ({
|
export const getOctokit = jest.fn();
|
||||||
rest: {
|
|
||||||
repos: {
|
|
||||||
getCommit: jest.fn(() =>
|
|
||||||
Promise.resolve({
|
|
||||||
data: {
|
|
||||||
commit: {
|
|
||||||
committer: {
|
|
||||||
date: '2024-11-13T13:42:28Z'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
|
@ -5,12 +5,9 @@ import * as path from 'path';
|
||||||
import {Context} from '@actions/github/lib/context';
|
import {Context} from '@actions/github/lib/context';
|
||||||
import {Git} from '@docker/actions-toolkit/lib/git';
|
import {Git} from '@docker/actions-toolkit/lib/git';
|
||||||
import {GitHub} from '@docker/actions-toolkit/lib/github';
|
import {GitHub} from '@docker/actions-toolkit/lib/github';
|
||||||
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
|
|
||||||
|
|
||||||
import {ContextSource, getContext, getInputs, Inputs} from '../src/context';
|
import {ContextSource, getContext, getInputs, Inputs} from '../src/context';
|
||||||
|
|
||||||
const toolkit = new Toolkit({githubToken: 'fake-github-token'});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
jest.spyOn(GitHub, 'context', 'get').mockImplementation((): Context => {
|
jest.spyOn(GitHub, 'context', 'get').mockImplementation((): Context => {
|
||||||
|
@ -116,10 +113,9 @@ describe('getContext', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('workflow', async () => {
|
it('workflow', async () => {
|
||||||
const context = await getContext(ContextSource.workflow, toolkit);
|
const context = await getContext(ContextSource.workflow);
|
||||||
expect(context.ref).toEqual('refs/heads/dev');
|
expect(context.ref).toEqual('refs/heads/dev');
|
||||||
expect(context.sha).toEqual('5f3331d7f7044c18ca9f12c77d961c4d7cf3276a');
|
expect(context.sha).toEqual('5f3331d7f7044c18ca9f12c77d961c4d7cf3276a');
|
||||||
expect(context.commitDate).toEqual(new Date('2024-11-13T13:42:28.000Z'));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('git', async () => {
|
it('git', async () => {
|
||||||
|
@ -129,13 +125,9 @@ describe('getContext', () => {
|
||||||
sha: 'git-test-sha'
|
sha: 'git-test-sha'
|
||||||
} as Context);
|
} as Context);
|
||||||
});
|
});
|
||||||
jest.spyOn(Git, 'commitDate').mockImplementation(async (): Promise<Date> => {
|
const context = await getContext(ContextSource.git);
|
||||||
return new Date('2023-01-01T13:42:28.000Z');
|
|
||||||
});
|
|
||||||
const context = await getContext(ContextSource.git, toolkit);
|
|
||||||
expect(context.ref).toEqual('refs/heads/git-test');
|
expect(context.ref).toEqual('refs/heads/git-test');
|
||||||
expect(context.sha).toEqual('git-test-sha');
|
expect(context.sha).toEqual('git-test-sha');
|
||||||
expect(context.commitDate).toEqual(new Date('2023-01-01T13:42:28.000Z'));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,10 @@ import {beforeEach, describe, expect, jest, test} from '@jest/globals';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as dotenv from 'dotenv';
|
import * as dotenv from 'dotenv';
|
||||||
|
|
||||||
import {Context} from '@actions/github/lib/context';
|
|
||||||
import {GitHub} from '@docker/actions-toolkit/lib/github';
|
import {GitHub} from '@docker/actions-toolkit/lib/github';
|
||||||
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
|
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
|
||||||
import {GitHubRepo} from '@docker/actions-toolkit/lib/types/github';
|
import {GitHubRepo} from '@docker/actions-toolkit/lib/types/github';
|
||||||
|
import {Context} from '@actions/github/lib/context';
|
||||||
|
|
||||||
import {ContextSource, getContext, getInputs, Inputs} from '../src/context';
|
import {ContextSource, getContext, getInputs, Inputs} from '../src/context';
|
||||||
import {Meta, Version} from '../src/meta';
|
import {Meta, Version} from '../src/meta';
|
||||||
|
@ -32,16 +31,8 @@ beforeEach(() => {
|
||||||
delete process.env[key];
|
delete process.env[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.spyOn(GitHub, 'context', 'get').mockImplementation((): Context => {
|
jest.spyOn(GitHub, 'context', 'get').mockImplementation((): Context => {
|
||||||
//@ts-expect-error partial info
|
return new Context();
|
||||||
return {
|
|
||||||
...new Context(),
|
|
||||||
repo: {
|
|
||||||
owner: 'docker',
|
|
||||||
repo: 'repo'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -62,7 +53,7 @@ const tagsLabelsTest = async (name: string, envFile: string, inputs: Inputs, exV
|
||||||
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
||||||
const toolkit = new Toolkit();
|
const toolkit = new Toolkit();
|
||||||
const repo = await toolkit.github.repoData();
|
const repo = await toolkit.github.repoData();
|
||||||
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow, toolkit), repo);
|
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow), repo);
|
||||||
|
|
||||||
const version = meta.version;
|
const version = meta.version;
|
||||||
expect(version).toEqual(exVersion);
|
expect(version).toEqual(exVersion);
|
||||||
|
@ -631,7 +622,6 @@ describe('push', () => {
|
||||||
tags: [
|
tags: [
|
||||||
`type=raw,value=mytag-{{branch}}`,
|
`type=raw,value=mytag-{{branch}}`,
|
||||||
`type=raw,value=mytag-{{date 'YYYYMMDD'}}`,
|
`type=raw,value=mytag-{{date 'YYYYMMDD'}}`,
|
||||||
`type=raw,value=mytag-cd-{{commit_date 'YYYYMMDD'}}`,
|
|
||||||
`type=raw,value=mytag-{{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}`,
|
`type=raw,value=mytag-{{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}`,
|
||||||
`type=raw,value=mytag-tag-{{tag}}`,
|
`type=raw,value=mytag-tag-{{tag}}`,
|
||||||
`type=raw,value=mytag-baseref-{{base_ref}}`,
|
`type=raw,value=mytag-baseref-{{base_ref}}`,
|
||||||
|
@ -642,7 +632,6 @@ describe('push', () => {
|
||||||
main: 'mytag-master',
|
main: 'mytag-master',
|
||||||
partial: [
|
partial: [
|
||||||
'mytag-20200110',
|
'mytag-20200110',
|
||||||
"mytag-cd-20200110",
|
|
||||||
'mytag-20200110-093000',
|
'mytag-20200110-093000',
|
||||||
'mytag-tag-',
|
'mytag-tag-',
|
||||||
'mytag-baseref-',
|
'mytag-baseref-',
|
||||||
|
@ -653,7 +642,6 @@ describe('push', () => {
|
||||||
[
|
[
|
||||||
'user/app:mytag-master',
|
'user/app:mytag-master',
|
||||||
'user/app:mytag-20200110',
|
'user/app:mytag-20200110',
|
||||||
'user/app:mytag-cd-20200110',
|
|
||||||
'user/app:mytag-20200110-093000',
|
'user/app:mytag-20200110-093000',
|
||||||
'user/app:mytag-tag-',
|
'user/app:mytag-tag-',
|
||||||
'user/app:mytag-baseref-',
|
'user/app:mytag-baseref-',
|
||||||
|
@ -780,21 +768,16 @@ describe('push', () => {
|
||||||
`type=raw,value=mytag-{{branch}}`,
|
`type=raw,value=mytag-{{branch}}`,
|
||||||
`type=raw,value=mytag-{{date 'YYYYMMDD'}}`,
|
`type=raw,value=mytag-{{date 'YYYYMMDD'}}`,
|
||||||
`type=raw,value=mytag-{{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}`,
|
`type=raw,value=mytag-{{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}`,
|
||||||
`type=raw,value=mytag-src-{{commit_date 'YYYYMMDD'}}`,
|
|
||||||
`type=raw,value=mytag-tag-{{tag}}`,
|
`type=raw,value=mytag-tag-{{tag}}`,
|
||||||
`type=raw,value=mytag-baseref-{{base_ref}}`,
|
`type=raw,value=mytag-baseref-{{base_ref}}`,
|
||||||
`type=raw,value=mytag-defbranch,enable={{is_default_branch}}`
|
`type=raw,value=mytag-defbranch,enable={{is_default_branch}}`
|
||||||
],
|
],
|
||||||
labels: [
|
|
||||||
"org.opencontainers.image.created={{commit_date 'YYYY-MM-DDTHH:mm:ss.SSS[Z]'}}"
|
|
||||||
]
|
|
||||||
} as Inputs,
|
} as Inputs,
|
||||||
{
|
{
|
||||||
main: 'mytag-master',
|
main: 'mytag-master',
|
||||||
partial: [
|
partial: [
|
||||||
'mytag-20200110',
|
'mytag-20200110',
|
||||||
'mytag-20200110-093000',
|
'mytag-20200110-093000',
|
||||||
'mytag-src-20200110',
|
|
||||||
'mytag-tag-',
|
'mytag-tag-',
|
||||||
'mytag-baseref-',
|
'mytag-baseref-',
|
||||||
'mytag-defbranch'
|
'mytag-defbranch'
|
||||||
|
@ -805,7 +788,6 @@ describe('push', () => {
|
||||||
'mytag-master',
|
'mytag-master',
|
||||||
'mytag-20200110',
|
'mytag-20200110',
|
||||||
'mytag-20200110-093000',
|
'mytag-20200110-093000',
|
||||||
'mytag-src-20200110',
|
|
||||||
'mytag-tag-',
|
'mytag-tag-',
|
||||||
'mytag-baseref-',
|
'mytag-baseref-',
|
||||||
'mytag-defbranch'
|
'mytag-defbranch'
|
||||||
|
@ -2639,35 +2621,6 @@ describe('pr', () => {
|
||||||
],
|
],
|
||||||
undefined
|
undefined
|
||||||
],
|
],
|
||||||
[
|
|
||||||
'pr12',
|
|
||||||
'event_pull_request.env',
|
|
||||||
{
|
|
||||||
images: ['org/app'],
|
|
||||||
tags: [
|
|
||||||
`type=raw,value={{commit_date YYYY-MM-DD-HHmmSS}}`,
|
|
||||||
]
|
|
||||||
} as Inputs,
|
|
||||||
{
|
|
||||||
main: "2020-01-10T00-30-00Z",
|
|
||||||
partial: [],
|
|
||||||
latest: false
|
|
||||||
} as Version,
|
|
||||||
[
|
|
||||||
'org/app:2020-01-10T00-30-00Z'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
|
|
||||||
"org.opencontainers.image.description=This your first repo!",
|
|
||||||
"org.opencontainers.image.licenses=MIT",
|
|
||||||
"org.opencontainers.image.revision=a9c8c5828b91be19d9728548b24759e352367ef1",
|
|
||||||
"org.opencontainers.image.source=https://github.com/octocat/Hello-World",
|
|
||||||
"org.opencontainers.image.title=Hello-World",
|
|
||||||
"org.opencontainers.image.url=https://github.com/octocat/Hello-World",
|
|
||||||
"org.opencontainers.image.version=2020-01-10T00-30-00Z"
|
|
||||||
],
|
|
||||||
undefined
|
|
||||||
],
|
|
||||||
])('given %p with %p event', tagsLabelsTest);
|
])('given %p with %p event', tagsLabelsTest);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3016,41 +2969,13 @@ describe('pr-head-sha', () => {
|
||||||
"org.opencontainers.image.version=mytag-master"
|
"org.opencontainers.image.version=mytag-master"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
|
||||||
'pr12',
|
|
||||||
'event_pull_request.env',
|
|
||||||
{
|
|
||||||
images: ['org/app'],
|
|
||||||
tags: [
|
|
||||||
`type=raw,value=src-{{commit_date YYYY-MM-DD}}`,
|
|
||||||
]
|
|
||||||
} as Inputs,
|
|
||||||
{
|
|
||||||
main: "src-2020-01-10T00-30-00Z",
|
|
||||||
partial: [],
|
|
||||||
latest: false
|
|
||||||
} as Version,
|
|
||||||
[
|
|
||||||
"org/app:src-2020-01-10T00-30-00Z",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
|
|
||||||
"org.opencontainers.image.description=This your first repo!",
|
|
||||||
"org.opencontainers.image.licenses=MIT",
|
|
||||||
"org.opencontainers.image.revision=3370e228f2209994d57af4427fe64e71bb79ac96",
|
|
||||||
"org.opencontainers.image.source=https://github.com/octocat/Hello-World",
|
|
||||||
"org.opencontainers.image.title=Hello-World",
|
|
||||||
"org.opencontainers.image.url=https://github.com/octocat/Hello-World",
|
|
||||||
"org.opencontainers.image.version=src-2020-01-10T00-30-00Z",
|
|
||||||
]
|
|
||||||
],
|
|
||||||
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exVersion: Version, exTags: Array<string>, exLabelsAnnotations: Array<string>) => {
|
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exVersion: Version, exTags: Array<string>, exLabelsAnnotations: Array<string>) => {
|
||||||
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
||||||
process.env.DOCKER_METADATA_PR_HEAD_SHA = 'true';
|
process.env.DOCKER_METADATA_PR_HEAD_SHA = 'true';
|
||||||
|
|
||||||
const toolkit = new Toolkit();
|
const toolkit = new Toolkit();
|
||||||
const repo = await toolkit.github.repoData();
|
const repo = await toolkit.github.repoData();
|
||||||
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow, toolkit), repo);
|
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow), repo);
|
||||||
|
|
||||||
const version = meta.version;
|
const version = meta.version;
|
||||||
expect(version).toEqual(exVersion);
|
expect(version).toEqual(exVersion);
|
||||||
|
@ -3103,20 +3028,16 @@ describe('schedule', () => {
|
||||||
{
|
{
|
||||||
images: ['user/app'],
|
images: ['user/app'],
|
||||||
tags: [
|
tags: [
|
||||||
`type=schedule,pattern={{date 'YYYYMMDD'}}`,
|
`type=schedule,pattern={{date 'YYYYMMDD'}}`
|
||||||
`type=schedule,pattern=source-date-{{commit_date 'YYYY-MM-DD'}}`
|
|
||||||
]
|
]
|
||||||
} as Inputs,
|
} as Inputs,
|
||||||
{
|
{
|
||||||
main: '20200110',
|
main: '20200110',
|
||||||
partial: [
|
partial: [],
|
||||||
"source-date-2020-01-10",
|
|
||||||
],
|
|
||||||
latest: false
|
latest: false
|
||||||
} as Version,
|
} as Version,
|
||||||
[
|
[
|
||||||
'user/app:20200110',
|
'user/app:20200110'
|
||||||
'user/app:source-date-2020-01-10'
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
|
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
|
||||||
|
@ -3300,20 +3221,16 @@ describe('schedule', () => {
|
||||||
{
|
{
|
||||||
images: ['user/app'],
|
images: ['user/app'],
|
||||||
tags: [
|
tags: [
|
||||||
`type=schedule,pattern={{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}`,
|
`type=schedule,pattern={{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}`
|
||||||
`type=schedule,pattern=src-{{commit_date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}`,
|
|
||||||
]
|
]
|
||||||
} as Inputs,
|
} as Inputs,
|
||||||
{
|
{
|
||||||
main: '20200110-093000',
|
main: '20200110-093000',
|
||||||
partial: [
|
partial: [],
|
||||||
"src-20200110-093000",
|
|
||||||
],
|
|
||||||
latest: false
|
latest: false
|
||||||
} as Version,
|
} as Version,
|
||||||
[
|
[
|
||||||
'user/app:20200110-093000',
|
'user/app:20200110-093000'
|
||||||
'user/app:src-20200110-093000'
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
|
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
|
||||||
|
@ -3395,39 +3312,6 @@ describe('release', () => {
|
||||||
"org.opencontainers.image.version=v1.1.1"
|
"org.opencontainers.image.version=v1.1.1"
|
||||||
],
|
],
|
||||||
undefined
|
undefined
|
||||||
],
|
|
||||||
[
|
|
||||||
'release03',
|
|
||||||
'event_release_created.env',
|
|
||||||
{
|
|
||||||
images: ['user/app'],
|
|
||||||
tags: [
|
|
||||||
`type=raw,value=src-{{commit_date 'YYYYMMDD-HHmmss'}}`,
|
|
||||||
`type=raw,value={{date 'YYYYMMDD-HHmmss'}}`,
|
|
||||||
]
|
|
||||||
} as Inputs,
|
|
||||||
{
|
|
||||||
"main": "src-20200110-003000",
|
|
||||||
partial: [
|
|
||||||
"20200110-003000",
|
|
||||||
],
|
|
||||||
"latest": false,
|
|
||||||
} as Version,
|
|
||||||
[
|
|
||||||
"user/app:src-20200110-003000",
|
|
||||||
"user/app:20200110-003000",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
|
|
||||||
"org.opencontainers.image.description=This your first repo!",
|
|
||||||
"org.opencontainers.image.licenses=MIT",
|
|
||||||
"org.opencontainers.image.revision=860c1904a1ce19322e91ac35af1ab07466440c37",
|
|
||||||
"org.opencontainers.image.source=https://github.com/octocat/Hello-World",
|
|
||||||
"org.opencontainers.image.title=Hello-World",
|
|
||||||
"org.opencontainers.image.url=https://github.com/octocat/Hello-World",
|
|
||||||
"org.opencontainers.image.version=src-20200110-003000",
|
|
||||||
],
|
|
||||||
undefined
|
|
||||||
]
|
]
|
||||||
])('given %s with %p event', tagsLabelsTest);
|
])('given %s with %p event', tagsLabelsTest);
|
||||||
});
|
});
|
||||||
|
@ -4128,7 +4012,7 @@ describe('json', () => {
|
||||||
|
|
||||||
const toolkit = new Toolkit();
|
const toolkit = new Toolkit();
|
||||||
const repo = await toolkit.github.repoData();
|
const repo = await toolkit.github.repoData();
|
||||||
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow,toolkit), repo);
|
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow), repo);
|
||||||
|
|
||||||
const jsonOutput = meta.getJSON(['manifest']);
|
const jsonOutput = meta.getJSON(['manifest']);
|
||||||
expect(jsonOutput).toEqual(exJSON);
|
expect(jsonOutput).toEqual(exJSON);
|
||||||
|
@ -4644,7 +4528,7 @@ describe('bakeFile', () => {
|
||||||
|
|
||||||
const toolkit = new Toolkit();
|
const toolkit = new Toolkit();
|
||||||
const repo = await toolkit.github.repoData();
|
const repo = await toolkit.github.repoData();
|
||||||
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow,toolkit), repo);
|
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow), repo);
|
||||||
|
|
||||||
const bakeFileTags = meta.getBakeFile('tags');
|
const bakeFileTags = meta.getBakeFile('tags');
|
||||||
expect(JSON.parse(fs.readFileSync(bakeFileTags, 'utf8'))).toEqual(exBakeTags);
|
expect(JSON.parse(fs.readFileSync(bakeFileTags, 'utf8'))).toEqual(exBakeTags);
|
||||||
|
@ -4708,7 +4592,7 @@ describe('bakeFileTagsLabels', () => {
|
||||||
|
|
||||||
const toolkit = new Toolkit();
|
const toolkit = new Toolkit();
|
||||||
const repo = await toolkit.github.repoData();
|
const repo = await toolkit.github.repoData();
|
||||||
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow,toolkit), repo);
|
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow), repo);
|
||||||
|
|
||||||
const bakeFile = meta.getBakeFileTagsLabels();
|
const bakeFile = meta.getBakeFileTagsLabels();
|
||||||
expect(JSON.parse(fs.readFileSync(bakeFile, 'utf8'))).toEqual(exBakeDefinition);
|
expect(JSON.parse(fs.readFileSync(bakeFile, 'utf8'))).toEqual(exBakeDefinition);
|
||||||
|
@ -4754,10 +4638,8 @@ describe('sepTags', () => {
|
||||||
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
||||||
|
|
||||||
const toolkit = new Toolkit();
|
const toolkit = new Toolkit();
|
||||||
|
|
||||||
const repo = await toolkit.github.repoData();
|
const repo = await toolkit.github.repoData();
|
||||||
|
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow), repo);
|
||||||
const meta = new Meta({...getInputs(), ...inputs}, await getContext(ContextSource.workflow, toolkit), repo);
|
|
||||||
|
|
||||||
expect(meta.getTags().join(inputs.sepTags)).toEqual(expTags);
|
expect(meta.getTags().join(inputs.sepTags)).toEqual(expTags);
|
||||||
});
|
});
|
||||||
|
|
|
@ -59,7 +59,7 @@ outputs:
|
||||||
bake-file-labels:
|
bake-file-labels:
|
||||||
description: 'Bake definition file with labels'
|
description: 'Bake definition file with labels'
|
||||||
bake-file-annotations:
|
bake-file-annotations:
|
||||||
description: 'Bake definition file with annotations'
|
description: 'Bake definiton file with annotations'
|
||||||
bake-file:
|
bake-file:
|
||||||
description: 'Bake definition file with tags and labels'
|
description: 'Bake definition file with tags and labels'
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,9 @@ ARG NODE_VERSION=20
|
||||||
FROM node:${NODE_VERSION}-alpine AS base
|
FROM node:${NODE_VERSION}-alpine AS base
|
||||||
RUN apk add --no-cache cpio findutils git
|
RUN apk add --no-cache cpio findutils git
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
RUN --mount=type=bind,target=.,rw \
|
|
||||||
--mount=type=cache,target=/src/.yarn/cache <<EOT
|
|
||||||
corepack enable
|
|
||||||
yarn --version
|
|
||||||
yarn config set --home enableTelemetry 0
|
|
||||||
EOT
|
|
||||||
|
|
||||||
FROM base AS deps
|
FROM base AS deps
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/.yarn/cache \
|
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
yarn install && mkdir /vendor && cp yarn.lock /vendor
|
yarn install && mkdir /vendor && cp yarn.lock /vendor
|
||||||
|
|
||||||
|
@ -27,7 +20,7 @@ RUN --mount=type=bind,target=.,rw <<EOT
|
||||||
git add -A
|
git add -A
|
||||||
cp -rf /vendor/* .
|
cp -rf /vendor/* .
|
||||||
if [ -n "$(git status --porcelain -- yarn.lock)" ]; then
|
if [ -n "$(git status --porcelain -- yarn.lock)" ]; then
|
||||||
echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor"'
|
echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'
|
||||||
git status --porcelain -- yarn.lock
|
git status --porcelain -- yarn.lock
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -35,7 +28,6 @@ EOT
|
||||||
|
|
||||||
FROM deps AS build
|
FROM deps AS build
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/.yarn/cache \
|
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
yarn run build && mkdir /out && cp -Rf dist /out/
|
yarn run build && mkdir /out && cp -Rf dist /out/
|
||||||
|
|
||||||
|
@ -56,23 +48,22 @@ EOT
|
||||||
|
|
||||||
FROM deps AS format
|
FROM deps AS format
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/.yarn/cache \
|
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
yarn run format \
|
yarn run format \
|
||||||
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' -not -path './.yarn/*' | cpio -pdm /out
|
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' | cpio -pdm /out
|
||||||
|
|
||||||
FROM scratch AS format-update
|
FROM scratch AS format-update
|
||||||
COPY --from=format /out /
|
COPY --from=format /out /
|
||||||
|
|
||||||
FROM deps AS lint
|
FROM deps AS lint
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/.yarn/cache \
|
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
yarn run lint
|
yarn run lint
|
||||||
|
|
||||||
FROM deps AS test
|
FROM deps AS test
|
||||||
|
ENV RUNNER_TEMP=/tmp/github_runner
|
||||||
|
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/.yarn/cache \
|
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
yarn run test --coverage --coverageDirectory=/tmp/coverage
|
yarn run test --coverage --coverageDirectory=/tmp/coverage
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -1,15 +1,9 @@
|
||||||
target "_common" {
|
|
||||||
args = {
|
|
||||||
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
group "default" {
|
group "default" {
|
||||||
targets = ["build"]
|
targets = ["build"]
|
||||||
}
|
}
|
||||||
|
|
||||||
group "pre-checkin" {
|
group "pre-checkin" {
|
||||||
targets = ["vendor", "format", "build"]
|
targets = ["vendor-update", "format", "build"]
|
||||||
}
|
}
|
||||||
|
|
||||||
group "validate" {
|
group "validate" {
|
||||||
|
@ -17,49 +11,42 @@ group "validate" {
|
||||||
}
|
}
|
||||||
|
|
||||||
target "build" {
|
target "build" {
|
||||||
inherits = ["_common"]
|
|
||||||
dockerfile = "dev.Dockerfile"
|
dockerfile = "dev.Dockerfile"
|
||||||
target = "build-update"
|
target = "build-update"
|
||||||
output = ["."]
|
output = ["."]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "build-validate" {
|
target "build-validate" {
|
||||||
inherits = ["_common"]
|
|
||||||
dockerfile = "dev.Dockerfile"
|
dockerfile = "dev.Dockerfile"
|
||||||
target = "build-validate"
|
target = "build-validate"
|
||||||
output = ["type=cacheonly"]
|
output = ["type=cacheonly"]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "format" {
|
target "format" {
|
||||||
inherits = ["_common"]
|
|
||||||
dockerfile = "dev.Dockerfile"
|
dockerfile = "dev.Dockerfile"
|
||||||
target = "format-update"
|
target = "format-update"
|
||||||
output = ["."]
|
output = ["."]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "lint" {
|
target "lint" {
|
||||||
inherits = ["_common"]
|
|
||||||
dockerfile = "dev.Dockerfile"
|
dockerfile = "dev.Dockerfile"
|
||||||
target = "lint"
|
target = "lint"
|
||||||
output = ["type=cacheonly"]
|
output = ["type=cacheonly"]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "vendor" {
|
target "vendor-update" {
|
||||||
inherits = ["_common"]
|
|
||||||
dockerfile = "dev.Dockerfile"
|
dockerfile = "dev.Dockerfile"
|
||||||
target = "vendor-update"
|
target = "vendor-update"
|
||||||
output = ["."]
|
output = ["."]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "vendor-validate" {
|
target "vendor-validate" {
|
||||||
inherits = ["_common"]
|
|
||||||
dockerfile = "dev.Dockerfile"
|
dockerfile = "dev.Dockerfile"
|
||||||
target = "vendor-validate"
|
target = "vendor-validate"
|
||||||
output = ["type=cacheonly"]
|
output = ["type=cacheonly"]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "test" {
|
target "test" {
|
||||||
inherits = ["_common"]
|
|
||||||
dockerfile = "dev.Dockerfile"
|
dockerfile = "dev.Dockerfile"
|
||||||
target = "test-coverage"
|
target = "test-coverage"
|
||||||
output = ["./coverage"]
|
output = ["./coverage"]
|
||||||
|
|
50
package.json
50
package.json
|
@ -1,16 +1,17 @@
|
||||||
{
|
{
|
||||||
"name": "docker-metadata-action",
|
"name": "docker-metadata-action",
|
||||||
"description": "GitHub Action to extract metadata (tags, labels) for Docker",
|
"description": "GitHub Action to extract metadata (tags, labels) for Docker",
|
||||||
"main": "src/main.ts",
|
"main": "lib/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "ncc build --source-map --minify --license licenses.txt",
|
"build": "ncc build src/main.ts --source-map --minify --license licenses.txt",
|
||||||
"lint": "yarn run prettier && yarn run eslint",
|
"lint": "yarn run prettier && yarn run eslint",
|
||||||
"format": "yarn run prettier:fix && yarn run eslint:fix",
|
"format": "yarn run prettier:fix && yarn run eslint:fix",
|
||||||
"eslint": "eslint --max-warnings=0 .",
|
"eslint": "eslint --max-warnings=0 .",
|
||||||
"eslint:fix": "eslint --fix .",
|
"eslint:fix": "eslint --fix .",
|
||||||
"prettier": "prettier --check \"./**/*.ts\"",
|
"prettier": "prettier --check \"./**/*.ts\"",
|
||||||
"prettier:fix": "prettier --write \"./**/*.ts\"",
|
"prettier:fix": "prettier --write \"./**/*.ts\"",
|
||||||
"test": "jest"
|
"test": "jest",
|
||||||
|
"all": "yarn run build && yarn run format && yarn test"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -25,34 +26,33 @@
|
||||||
],
|
],
|
||||||
"author": "Docker Inc.",
|
"author": "Docker Inc.",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"packageManager": "yarn@3.6.3",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^1.10.1",
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^6.0.0",
|
||||||
"@docker/actions-toolkit": "^0.56.0",
|
"@docker/actions-toolkit": "^0.14.0",
|
||||||
"@renovate/pep440": "^1.0.0",
|
"@renovate/pep440": "^1.0.0",
|
||||||
"csv-parse": "^5.6.0",
|
"csv-parse": "^5.5.2",
|
||||||
"handlebars": "^4.7.8",
|
"handlebars": "^4.7.8",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.29.4",
|
||||||
"moment-timezone": "^0.5.47",
|
"moment-timezone": "^0.5.43",
|
||||||
"semver": "^7.7.1"
|
"semver": "^7.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/csv-parse": "^1.2.2",
|
"@types/csv-parse": "^1.2.2",
|
||||||
"@types/node": "^20.12.12",
|
"@types/node": "^20.5.9",
|
||||||
"@types/semver": "^7.5.8",
|
"@types/semver": "^7.5.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
"@typescript-eslint/eslint-plugin": "^6.6.0",
|
||||||
"@typescript-eslint/parser": "^7.9.0",
|
"@typescript-eslint/parser": "^6.6.0",
|
||||||
"@vercel/ncc": "^0.38.1",
|
"@vercel/ncc": "^0.38.0",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.3.1",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.48.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-jest": "^28.5.0",
|
"eslint-plugin-jest": "^27.2.3",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.0.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.6.4",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.0.3",
|
||||||
"ts-jest": "^29.1.2",
|
"ts-jest": "^29.1.1",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import {Context as GithubContext} from '@actions/github/lib/context';
|
import {Context} from '@actions/github/lib/context';
|
||||||
import {Util} from '@docker/actions-toolkit/lib/util';
|
import {Util} from '@docker/actions-toolkit/lib/util';
|
||||||
import {Git} from '@docker/actions-toolkit/lib/git';
|
import {Git} from '@docker/actions-toolkit/lib/git';
|
||||||
import {GitHub} from '@docker/actions-toolkit/lib/github';
|
import {GitHub} from '@docker/actions-toolkit/lib/github';
|
||||||
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
|
|
||||||
|
|
||||||
export interface Context extends GithubContext {
|
|
||||||
commitDate: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Inputs {
|
export interface Inputs {
|
||||||
context: ContextSource;
|
context: ContextSource;
|
||||||
|
@ -44,10 +39,10 @@ export enum ContextSource {
|
||||||
git = 'git'
|
git = 'git'
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getContext(source: ContextSource, toolkit: Toolkit): Promise<Context> {
|
export async function getContext(source: ContextSource): Promise<Context> {
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case ContextSource.workflow:
|
case ContextSource.workflow:
|
||||||
return await getContextFromWorkflow(toolkit);
|
return getContextFromWorkflow();
|
||||||
case ContextSource.git:
|
case ContextSource.git:
|
||||||
return await getContextFromGit();
|
return await getContextFromGit();
|
||||||
default:
|
default:
|
||||||
|
@ -55,7 +50,7 @@ export async function getContext(source: ContextSource, toolkit: Toolkit): Promi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getContextFromWorkflow(toolkit: Toolkit): Promise<Context> {
|
function getContextFromWorkflow(): Context {
|
||||||
const context = GitHub.context;
|
const context = GitHub.context;
|
||||||
|
|
||||||
// Needs to override Git reference with pr ref instead of upstream branch ref
|
// Needs to override Git reference with pr ref instead of upstream branch ref
|
||||||
|
@ -74,63 +69,9 @@ async function getContextFromWorkflow(toolkit: Toolkit): Promise<Context> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return context;
|
||||||
commitDate: await getCommitDateFromWorkflow(context.sha, toolkit),
|
|
||||||
...context
|
|
||||||
} as Context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getContextFromGit(): Promise<Context> {
|
async function getContextFromGit(): Promise<Context> {
|
||||||
const ctx = await Git.context();
|
return await Git.context();
|
||||||
|
|
||||||
return {
|
|
||||||
commitDate: await Git.commitDate(ctx.sha),
|
|
||||||
...ctx
|
|
||||||
} as Context;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getCommitDateFromWorkflow(sha: string, toolkit: Toolkit): Promise<Date> {
|
|
||||||
const event = GitHub.context.payload as unknown as {
|
|
||||||
// branch push
|
|
||||||
commits?: Array<{
|
|
||||||
timestamp: string;
|
|
||||||
// commit sha
|
|
||||||
id: string;
|
|
||||||
}>;
|
|
||||||
// tags
|
|
||||||
head_commit?: {
|
|
||||||
timestamp: string;
|
|
||||||
// commit sha
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
if (event.commits) {
|
|
||||||
const commitDate = event.commits.find(x => x.id === sha)?.timestamp;
|
|
||||||
if (commitDate) {
|
|
||||||
return new Date(commitDate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.head_commit) {
|
|
||||||
if (event.head_commit.id === sha) {
|
|
||||||
return new Date(event.head_commit.timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fallback to github api for commit date
|
|
||||||
try {
|
|
||||||
const commit = await toolkit.github.octokit.rest.repos.getCommit({
|
|
||||||
owner: GitHub.context.repo.owner,
|
|
||||||
repo: GitHub.context.repo.repo,
|
|
||||||
ref: sha
|
|
||||||
});
|
|
||||||
if (commit.data.commit.committer?.date) {
|
|
||||||
return new Date(commit.data.commit.committer.date);
|
|
||||||
}
|
|
||||||
throw new Error('Committer date not found');
|
|
||||||
} catch (error) {
|
|
||||||
core.debug(`Failed to get commit date from GitHub API: ${error.message}`);
|
|
||||||
return new Date();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
24
src/main.ts
24
src/main.ts
|
@ -2,19 +2,22 @@ import * as fs from 'fs';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as actionsToolkit from '@docker/actions-toolkit';
|
import * as actionsToolkit from '@docker/actions-toolkit';
|
||||||
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
|
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
|
||||||
import {Util} from '@docker/actions-toolkit/lib/util';
|
|
||||||
|
|
||||||
import {getContext, getInputs, Inputs} from './context';
|
import {getContext, getInputs, Inputs} from './context';
|
||||||
import {Meta, Version} from './meta';
|
import {Meta, Version} from './meta';
|
||||||
|
|
||||||
|
function setOutput(name: string, value: string) {
|
||||||
|
core.setOutput(name, value);
|
||||||
|
core.exportVariable(`DOCKER_METADATA_OUTPUT_${name.replace(/\W/g, '_').toUpperCase()}`, value);
|
||||||
|
}
|
||||||
|
|
||||||
actionsToolkit.run(
|
actionsToolkit.run(
|
||||||
// main
|
// main
|
||||||
async () => {
|
async () => {
|
||||||
const inputs: Inputs = getInputs();
|
const inputs: Inputs = getInputs();
|
||||||
const toolkit = new Toolkit({githubToken: inputs.githubToken});
|
const toolkit = new Toolkit({githubToken: inputs.githubToken});
|
||||||
const context = await getContext(inputs.context, toolkit);
|
const context = await getContext(inputs.context);
|
||||||
const repo = await toolkit.github.repoData();
|
const repo = await toolkit.github.repoData();
|
||||||
const setOutput = outputEnvEnabled() ? setOutputAndEnv : core.setOutput;
|
|
||||||
|
|
||||||
await core.group(`Context info`, async () => {
|
await core.group(`Context info`, async () => {
|
||||||
core.info(`eventName: ${context.eventName}`);
|
core.info(`eventName: ${context.eventName}`);
|
||||||
|
@ -25,7 +28,6 @@ actionsToolkit.run(
|
||||||
core.info(`actor: ${context.actor}`);
|
core.info(`actor: ${context.actor}`);
|
||||||
core.info(`runNumber: ${context.runNumber}`);
|
core.info(`runNumber: ${context.runNumber}`);
|
||||||
core.info(`runId: ${context.runId}`);
|
core.info(`runId: ${context.runId}`);
|
||||||
core.info(`commitDate: ${context.commitDate}`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (core.isDebug()) {
|
if (core.isDebug()) {
|
||||||
|
@ -103,18 +105,6 @@ actionsToolkit.run(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bake file with tags and labels
|
// Bake file with tags and labels
|
||||||
setOutput(`bake-file`, `${meta.getBakeFileTagsLabels()}`);
|
setOutput(`bake-file`, meta.getBakeFileTagsLabels());
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
function setOutputAndEnv(name: string, value: string) {
|
|
||||||
core.setOutput(name, value);
|
|
||||||
core.exportVariable(`DOCKER_METADATA_OUTPUT_${name.replace(/\W/g, '_').toUpperCase()}`, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function outputEnvEnabled(): boolean {
|
|
||||||
if (process.env.DOCKER_METADATA_SET_OUTPUT_ENV) {
|
|
||||||
return Util.parseBool(process.env.DOCKER_METADATA_SET_OUTPUT_ENV);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
153
src/meta.ts
153
src/meta.ts
|
@ -5,16 +5,15 @@ import moment from 'moment-timezone';
|
||||||
import * as pep440 from '@renovate/pep440';
|
import * as pep440 from '@renovate/pep440';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
import {Context} from '@actions/github/lib/context';
|
||||||
import {Context as ToolkitContext} from '@docker/actions-toolkit/lib/context';
|
import {Context as ToolkitContext} from '@docker/actions-toolkit/lib/context';
|
||||||
import {GitHubRepo} from '@docker/actions-toolkit/lib/types/github';
|
import {GitHubRepo} from '@docker/actions-toolkit/lib/types/github';
|
||||||
|
|
||||||
import {Inputs, Context} from './context';
|
import {Inputs} from './context';
|
||||||
import * as icl from './image';
|
import * as icl from './image';
|
||||||
import * as tcl from './tag';
|
import * as tcl from './tag';
|
||||||
import * as fcl from './flavor';
|
import * as fcl from './flavor';
|
||||||
|
|
||||||
const defaultShortShaLength = 7;
|
|
||||||
|
|
||||||
export interface Version {
|
export interface Version {
|
||||||
main: string | undefined;
|
main: string | undefined;
|
||||||
partial: string[];
|
partial: string[];
|
||||||
|
@ -114,7 +113,6 @@ export class Meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentDate = this.date;
|
const currentDate = this.date;
|
||||||
const commitDate = this.context.commitDate;
|
|
||||||
const vraw = this.setValue(
|
const vraw = this.setValue(
|
||||||
handlebars.compile(tag.attrs['pattern'])({
|
handlebars.compile(tag.attrs['pattern'])({
|
||||||
date: function (format, options) {
|
date: function (format, options) {
|
||||||
|
@ -130,20 +128,6 @@ export class Meta {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return m.tz(tz).format(format);
|
return m.tz(tz).format(format);
|
||||||
},
|
|
||||||
commit_date: function (format, options) {
|
|
||||||
const m = moment(commitDate);
|
|
||||||
let tz = 'UTC';
|
|
||||||
Object.keys(options.hash).forEach(key => {
|
|
||||||
switch (key) {
|
|
||||||
case 'tz':
|
|
||||||
tz = options.hash[key];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error(`Unknown ${key} attribute`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return m.tz(tz).format(format);
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
tag
|
tag
|
||||||
|
@ -323,7 +307,7 @@ export class Meta {
|
||||||
|
|
||||||
let val = this.context.sha;
|
let val = this.context.sha;
|
||||||
if (tag.attrs['format'] === tcl.ShaFormat.Short) {
|
if (tag.attrs['format'] === tcl.ShaFormat.Short) {
|
||||||
val = Meta.shortSha(this.context.sha);
|
val = this.context.sha.substring(0, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
const vraw = this.setValue(val, tag);
|
const vraw = this.setValue(val, tag);
|
||||||
|
@ -372,10 +356,9 @@ export class Meta {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
private setGlobalExp(val: string): string {
|
private setGlobalExp(val): string {
|
||||||
const context = this.context;
|
const context = this.context;
|
||||||
const currentDate = this.date;
|
const currentDate = this.date;
|
||||||
const commitDate = this.context.commitDate;
|
|
||||||
return handlebars.compile(val)({
|
return handlebars.compile(val)({
|
||||||
branch: function () {
|
branch: function () {
|
||||||
if (!/^refs\/heads\//.test(context.ref)) {
|
if (!/^refs\/heads\//.test(context.ref)) {
|
||||||
|
@ -390,7 +373,7 @@ export class Meta {
|
||||||
return context.ref.replace(/^refs\/tags\//g, '');
|
return context.ref.replace(/^refs\/tags\//g, '');
|
||||||
},
|
},
|
||||||
sha: function () {
|
sha: function () {
|
||||||
return Meta.shortSha(context.sha);
|
return context.sha.substring(0, 7);
|
||||||
},
|
},
|
||||||
base_ref: function () {
|
base_ref: function () {
|
||||||
if (/^refs\/tags\//.test(context.ref) && context.payload?.base_ref != undefined) {
|
if (/^refs\/tags\//.test(context.ref) && context.payload?.base_ref != undefined) {
|
||||||
|
@ -403,20 +386,6 @@ export class Meta {
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
commit_date: function (format, options) {
|
|
||||||
const m = moment(commitDate);
|
|
||||||
let tz = 'UTC';
|
|
||||||
Object.keys(options.hash).forEach(key => {
|
|
||||||
switch (key) {
|
|
||||||
case 'tz':
|
|
||||||
tz = options.hash[key];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error(`Unknown ${key} attribute`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return m.tz(tz).format(format);
|
|
||||||
},
|
|
||||||
is_default_branch: function () {
|
is_default_branch: function () {
|
||||||
const branch = context.ref.replace(/^refs\/heads\//g, '');
|
const branch = context.ref.replace(/^refs\/heads\//g, '');
|
||||||
// TODO: "base_ref" is available in the push payload but doesn't always seem to
|
// TODO: "base_ref" is available in the push payload but doesn't always seem to
|
||||||
|
@ -517,9 +486,7 @@ export class Meta {
|
||||||
`org.opencontainers.image.revision=${this.context.sha || ''}`,
|
`org.opencontainers.image.revision=${this.context.sha || ''}`,
|
||||||
`org.opencontainers.image.licenses=${this.repo.license?.spdx_id || ''}`
|
`org.opencontainers.image.licenses=${this.repo.license?.spdx_id || ''}`
|
||||||
];
|
];
|
||||||
extra.forEach(label => {
|
res.push(...extra);
|
||||||
res.push(this.setGlobalExp(label));
|
|
||||||
});
|
|
||||||
|
|
||||||
return Array.from(
|
return Array.from(
|
||||||
new Map<string, string>(
|
new Map<string, string>(
|
||||||
|
@ -555,66 +522,70 @@ export class Meta {
|
||||||
|
|
||||||
public getBakeFile(kind: string): string {
|
public getBakeFile(kind: string): string {
|
||||||
if (kind == 'tags') {
|
if (kind == 'tags') {
|
||||||
return this.generateBakeFile(
|
return this.generateBakeFile(kind, {
|
||||||
{
|
tags: this.getTags(),
|
||||||
tags: this.getTags(),
|
args: {
|
||||||
args: {
|
DOCKER_META_IMAGES: this.getImageNames().join(','),
|
||||||
DOCKER_META_IMAGES: this.getImageNames().join(','),
|
DOCKER_META_VERSION: this.version.main
|
||||||
DOCKER_META_VERSION: this.version.main
|
}
|
||||||
}
|
});
|
||||||
},
|
|
||||||
kind
|
|
||||||
);
|
|
||||||
} else if (kind == 'labels') {
|
} else if (kind == 'labels') {
|
||||||
return this.generateBakeFile(
|
return this.generateBakeFile(kind, {
|
||||||
{
|
labels: this.getLabels().reduce((res, label) => {
|
||||||
labels: this.getLabels().reduce((res, label) => {
|
const matches = label.match(/([^=]*)=(.*)/);
|
||||||
const matches = label.match(/([^=]*)=(.*)/);
|
if (!matches) {
|
||||||
if (!matches) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
res[matches[1]] = matches[2];
|
|
||||||
return res;
|
return res;
|
||||||
}, {})
|
}
|
||||||
},
|
res[matches[1]] = matches[2];
|
||||||
kind
|
return res;
|
||||||
);
|
}, {})
|
||||||
|
});
|
||||||
} else if (kind.startsWith('annotations:')) {
|
} else if (kind.startsWith('annotations:')) {
|
||||||
const name = kind.split(':')[0];
|
const name = kind.split(':')[0];
|
||||||
const annotations: Array<string> = [];
|
const annotations: Array<string> = [];
|
||||||
for (const level of kind.split(':')[1].split(',')) {
|
for (const level of kind.split(':')[1].split(',')) {
|
||||||
annotations.push(...this.getAnnotations().map(label => `${level}:${label}`));
|
annotations.push(...this.getAnnotations().map(label => `${level}:${label}`));
|
||||||
}
|
}
|
||||||
return this.generateBakeFile(
|
return this.generateBakeFile(name, {
|
||||||
{
|
annotations: annotations
|
||||||
annotations: annotations
|
});
|
||||||
},
|
|
||||||
name
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
throw new Error(`Unknown bake file type: ${kind}`);
|
throw new Error(`Unknown bake file type: ${kind}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getBakeFileTagsLabels(): string {
|
public getBakeFileTagsLabels(): string {
|
||||||
return this.generateBakeFile({
|
const bakeFile = path.join(ToolkitContext.tmpDir(), 'docker-metadata-action-bake.json');
|
||||||
tags: this.getTags(),
|
fs.writeFileSync(
|
||||||
labels: this.getLabels().reduce((res, label) => {
|
bakeFile,
|
||||||
const matches = label.match(/([^=]*)=(.*)/);
|
JSON.stringify(
|
||||||
if (!matches) {
|
{
|
||||||
return res;
|
target: {
|
||||||
}
|
[this.inputs.bakeTarget]: {
|
||||||
res[matches[1]] = matches[2];
|
tags: this.getTags(),
|
||||||
return res;
|
labels: this.getLabels().reduce((res, label) => {
|
||||||
}, {}),
|
const matches = label.match(/([^=]*)=(.*)/);
|
||||||
args: {
|
if (!matches) {
|
||||||
DOCKER_META_IMAGES: this.getImageNames().join(','),
|
return res;
|
||||||
DOCKER_META_VERSION: this.version.main
|
}
|
||||||
}
|
res[matches[1]] = matches[2];
|
||||||
});
|
return res;
|
||||||
|
}, {}),
|
||||||
|
args: {
|
||||||
|
DOCKER_META_IMAGES: this.getImageNames().join(','),
|
||||||
|
DOCKER_META_VERSION: this.version.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return bakeFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private generateBakeFile(dt, suffix?: string): string {
|
private generateBakeFile(name: string, dt): string {
|
||||||
const bakeFile = path.join(ToolkitContext.tmpDir(), `docker-metadata-action-bake${suffix ? `-${suffix}` : ''}.json`);
|
const bakeFile = path.join(ToolkitContext.tmpDir(), `docker-metadata-action-bake-${name}.json`);
|
||||||
fs.writeFileSync(bakeFile, JSON.stringify({target: {[this.inputs.bakeTarget]: dt}}, null, 2));
|
fs.writeFileSync(bakeFile, JSON.stringify({target: {[this.inputs.bakeTarget]: dt}}, null, 2));
|
||||||
return bakeFile;
|
return bakeFile;
|
||||||
}
|
}
|
||||||
|
@ -626,18 +597,4 @@ export class Meta {
|
||||||
private static sanitizeTag(tag: string): string {
|
private static sanitizeTag(tag: string): string {
|
||||||
return tag.replace(/[^a-zA-Z0-9._-]+/g, '-');
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue