-
Notifications
You must be signed in to change notification settings - Fork 214
152 lines (137 loc) · 6.04 KB
/
publish-dev.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# Publish flant/shell-operator-dev image to hub.docker.com and ghcr.io.
# Start when PR is labeled with 'publish/image/dev' or 'publish/image/dev/amd64'.
# Label 'publish/image/dev/amd64' publishes image only for amd64 arhitecture.
# Label 'publish/image/dev' publishes a multi-arch image, it is a long-lasting operation (~1h).
name: Publish dev image
on:
pull_request:
types: [labeled]
env:
QEMU_PLATFORMS: arm64,arm
BUILDX_PLATFORMS: "linux/amd64,linux/arm64,linux/arm/v7"
BUILDX_PLATFORMS_AMD64: "linux/amd64"
GHCR_IO_REPO: ghcr.io/flant/shell-operator-dev
jobs:
check:
name: Check and remove label
runs-on: ubuntu-latest
outputs:
run_publish: ${{ steps.check.outputs.run_publish }}
build_multi_arch: ${{ steps.check.outputs.build_multi_arch }}
steps:
- uses: actions/github-script@v6
id: check
with:
script: |
const PUBLISH_DEV_LABEL = 'publish/image/dev';
const PUBLISH_AMD64_LABEL = 'publish/image/dev/amd64';
const labelName = context.payload.label.name;
let runPublish = false;
let buildMultiArch = false;
if (labelName === PUBLISH_DEV_LABEL) {
runPublish = true;
buildMultiArch = true;
}
if (labelName === PUBLISH_AMD64_LABEL) {
runPublish = true;
}
if (!runPublish) {
return console.log(`Not a 'publish' label: '${labelName}'. Skip 'publish dev image'.`);
}
if (buildMultiArch) {
console.log(`Detect 'publish' label '${labelName}'. Remove label and run 'publish dev image' for all architectures.`);
} else {
console.log(`Detect 'publish' label '${labelName}'. Remove label and run 'publish dev image' for amd64 arch only.`);
}
core.setOutput('run_publish', 'true');
core.setOutput('build_multi_arch', buildMultiArch.toString());
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: labelName,
});
} catch (e) {
console.log(`Error occurred while remove label. Possibly label is already removed. Ignore '${typeof e}' error.`);
}
publish_dev_image:
name: Build and publish
runs-on: ubuntu-latest
needs:
- check
if: needs.check.outputs.run_publish == 'true'
steps:
- uses: actions/checkout@v4
- name: Prepare environment
env:
BUILD_MULTI_ARCH: ${{ needs.check.outputs.build_multi_arch }}
run: |
: Image name and version for dev image
# Example: dev-feat_branch-371e2d3b-2020.02.06_18:37:42
APP_VERSION=dev-${GITHUB_REF#refs/heads/}-${GITHUB_SHA::8}-$(date +'%Y.%m.%d_%H:%M:%S')
GHCR_IO_IMAGE_NAME="${GHCR_IO_REPO}:pr${{ github.event.pull_request.number }}"
echo "APP_VERSION=${APP_VERSION}" >> ${GITHUB_ENV}
echo "GHCR_IO_IMAGE_NAME=${GHCR_IO_IMAGE_NAME}" >> ${GITHUB_ENV}
echo "========================================="
echo "APP_VERSION = $APP_VERSION"
echo "GHCR_IO_IMAGE_NAME = $GHCR_IO_IMAGE_NAME"
echo "========================================="
if [[ ${BUILD_MULTI_ARCH} == "false" ]] ; then
echo "BUILDX_PLATFORMS=${BUILDX_PLATFORMS_AMD64}" >> ${GITHUB_ENV}
fi
echo "BUILD_MULTI_ARCH = ${BUILD_MULTI_ARCH}"
echo "BUILDX_PLATFORMS = ${BUILDX_PLATFORMS}"
echo "========================================="
- name: Set up QEMU
if: needs.check.outputs.build_multi_arch == 'true'
uses: docker/[email protected]
with:
platforms: "${{ env.QEMU_PLATFORMS }}"
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: Login to Github Container Registry
uses: docker/[email protected]
with:
registry: ghcr.io
username: ${{ secrets.GHCR_IO_USER }}
password: ${{ secrets.GHCR_IO_PASS }}
- name: Build and push using buildx
run: |
echo "Build ${GHCR_IO_IMAGE_NAME} with version '${APP_VERSION}'"
docker buildx build \
--platform $BUILDX_PLATFORMS \
--build-arg appVersion=$APP_VERSION \
--tag $GHCR_IO_IMAGE_NAME \
--push .
- name: Inspect binaries
if: needs.check.outputs.build_multi_arch == 'true'
run: |
# Image for one arhitecture has digest in config field.
# Image with multiple manifests has digest in each manifest.
manifests=$(docker buildx imagetools inspect "${GHCR_IO_IMAGE_NAME}" --raw)
if grep manifests <<<"${manifests}" 2>&1 >/dev/null ; then
jq -r '.manifests[]? | .digest + " " + .platform.os + "/" + .platform.architecture' <<<"${manifests}" \
| while read digest platform ; do
image=${GHCR_IO_IMAGE_NAME}@${digest}
if [[ ${BUILDX_PLATFORMS} != *"${platform}"* ]] ; then
echo "====================================="
echo "Ignore image for non-runnable platform ${platform}"
echo " ${image}"
echo "====================================="
continue
fi
echo "====================================="
echo "Inspect image for platform ${platform}"
echo " ${image}"
echo "====================================="
docker run --rm --platform ${platform} --entrypoint sh ${image} -c \
'apk add file > /dev/null; file /bin/kubectl; file /bin/busybox; file /shell-operator'
done
else
echo Not a multi-arhitecture image.
#echo $(echo -n "${manifests}" | openssl dgst -sha256) ' linux/amd64'
fi