4
4
// ECR repository: #{name}
5
5
6
6
function (name, region='ap-northeast-1' , platforms=['linux/arm64' ]) {
7
+ common:: {
8
+ setupSteps: [
9
+ { uses: 'docker/setup-buildx-action@v3' },
10
+ {
11
+ uses: 'aws-actions/configure-aws-credentials@v4' ,
12
+ with: {
13
+ 'aws-region' : region,
14
+ 'role-to-assume' : 'arn:aws:iam::005216166247:role/GhaDockerPush' ,
15
+ 'role-skip-session-tagging' : true ,
16
+ },
17
+ },
18
+ {
19
+ uses: 'aws-actions/amazon-ecr-login@v2' ,
20
+ id: 'login-ecr' ,
21
+ },
22
+ ],
23
+
24
+ runnersMap: {
25
+ 'linux/amd64' : 'ubuntu-24.04' ,
26
+ 'linux/arm64' : 'ubuntu-24.04-arm' ,
27
+ },
28
+ },
29
+
7
30
name: std.format ('docker-%s' , name),
8
31
on: {
9
32
push: {
@@ -16,34 +39,76 @@ function(name, region='ap-northeast-1', platforms=['linux/arm64']) {
16
39
},
17
40
jobs: {
18
41
build: {
19
- name: 'build' ,
20
- 'runs-on' : 'ubuntu-latest' ,
42
+ strategy: {
43
+ matrix: {
44
+ include: std.map (function (platform) {
45
+ key: std.strReplace (platform, '/' , '-' ), // for artifact name
46
+ platform: platform,
47
+ runner: $.common.runnersMap[platform],
48
+ }, platforms),
49
+ },
50
+ },
51
+ name: 'build (${{ matrix.platform }})' ,
52
+ 'runs-on' : '${{ matrix.runner }}' ,
21
53
permissions: { 'id-token' : 'write' , contents: 'read' },
22
- steps: [] +
23
- (if std.member(platforms, 'linux/arm64' ) then [{ uses: 'docker/setup-qemu-action@v2' }] else []) + [
24
- { uses: 'docker/setup-buildx-action@v2' },
54
+ steps: $.common.setupSteps + [
25
55
{
26
- uses: 'aws-actions/configure-aws-credentials@v1' ,
56
+ uses: 'docker/build-push-action@v6' ,
57
+ id: 'build-push' ,
27
58
with: {
28
- 'aws-region' : region ,
29
- 'role-to-assume' : 'arn:aws:iam::005216166247:role/GhaDockerPush ' ,
30
- 'role-skip-session-tagging' : true ,
59
+ context: std.format ( '{{defaultContext}}:%s' , name) ,
60
+ platforms : '${{ matrix.platform }} ' ,
61
+ outputs: std.format ( 'type=image,"name=${{ steps.login-ecr.outputs.registry }}/%s",push-by-digest=true,name-canonical=true,push=true' , name) ,
31
62
},
32
63
},
33
64
{
34
- uses: 'aws-actions/amazon-ecr-login@v1' ,
35
- id: 'login-ecr' ,
65
+ name: 'Export digests' ,
66
+ run: |||
67
+ mkdir -p "${RUNNER_TEMP}/digests"
68
+ printenv DIGEST > "${RUNNER_TEMP}/digests/${PLATFORM}"
69
+ ||| ,
70
+ env: {
71
+ RUNNER_TEMP: '${{ runner.temp }}' ,
72
+ DIGEST: '${{ steps.build-push.outputs.digest }}' ,
73
+ PLATFORM: '${{ matrix.key }}' ,
74
+ },
36
75
},
37
76
{
38
- uses: 'docker/build-push-action@v3' ,
77
+ name: 'Upload digests' ,
78
+ uses: 'actions/upload-artifact@v4' ,
39
79
with: {
40
- context: std.format ('{{defaultContext}}:%s' , name),
41
- platforms: std.join (',' , platforms),
42
- tags: std.join (',' , [
43
- std.format ('${{ steps.login-ecr.outputs.registry }}/%s:${{ github.sha }}' , name),
44
- std.format ('${{ steps.login-ecr.outputs.registry }}/%s:latest' , name),
45
- ]),
46
- push: true ,
80
+ name: 'digests-${{ matrix.key }}' ,
81
+ path: '${{ runner.temp }}/digests/*' ,
82
+ 'if-no-files-found' : 'error' ,
83
+ 'retention-days' : 1 ,
84
+ },
85
+ },
86
+ ],
87
+ },
88
+ merge: {
89
+ 'runs-on' : 'ubuntu-latest' ,
90
+ needs: ['build' ],
91
+ permissions: { 'id-token' : 'write' },
92
+ steps: $.common.setupSteps + [
93
+ {
94
+ name: 'Download digests' ,
95
+ uses: 'actions/download-artifact@v4' ,
96
+ with: {
97
+ path: '${{ runner.temp }}/digests' ,
98
+ pattern: 'digests-*' ,
99
+ 'merge-multiple' : true ,
100
+ },
101
+ },
102
+ {
103
+ name: 'Push manifest' ,
104
+ run: |||
105
+ cat "${RUNNER_TEMP}"/digests/* | xargs -I{} printf "%s@%s" "${REPO}" {} | docker buildx imagetools create -f /dev/stdin -t "${REPO}:latest" -t "${REPO}:${SHA}"
106
+ docker buildx imagetools inspect "${REPO}:${SHA}"
107
+ ||| ,
108
+ env: {
109
+ RUNNER_TEMP: '${{ runner.temp }}' ,
110
+ REPO: std.format ('${{ steps.login-ecr.outputs.registry }}/%s' , name),
111
+ SHA: '${{ github.sha }}' ,
47
112
},
48
113
},
49
114
],
0 commit comments