-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmany--build-and-push-image.yaml
More file actions
147 lines (140 loc) · 5.3 KB
/
many--build-and-push-image.yaml
File metadata and controls
147 lines (140 loc) · 5.3 KB
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
name: Build container image
# On pushes to the main branches, build and push the newly created docker
# images to the GitHub Container Repository where people can pull them from.
on:
push:
tags: [v*.*.*]
branches: [main, master, release, development]
paths:
- .github/workflows/many--build-and-push-image.yaml
- test/**
- lib/**
- src/**
- browser/**
- '*package*'
- '*tsconfig*'
- '*vitest*'
- '*eslint*'
- '*prettier*'
- '*[Dd]ocker*'
env:
IMAGE: image
TARGET: production
jobs:
build:
name: Build Container Image
runs-on: ubuntu-latest
outputs:
artifact_name: ${{ steps.artifact-name.outputs.name }}
full_tag: ${{ steps.vars.outputs.full_tag }}
tags: ${{ steps.vars.outputs.tags }}
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.1
- name: Get image tags
id: vars
shell: bash
run: |
# if tag is pushed then:
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
# Remove refs/tags/ from the github ref
FULL_TAG="${GITHUB_REF#refs/tags/}"
# Remove leading 'v' if present
VERSION="${FULL_TAG#v}"
echo "full_tag=$VERSION" >> $GITHUB_OUTPUT
if [[ "$VERSION" == *.*.*-* ]]; then
echo "tags=$VERSION" >> $GITHUB_OUTPUT
elif [[ "$VERSION" == *.*.* ]]; then
IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
tags="latest,$MAJOR.$MINOR.$PATCH,$MAJOR.$MINOR,$MAJOR"
echo "tags=$tags" >> $GITHUB_OUTPUT
else
echo "Tag: '$VERSION' is not a semver."
echo "Make sure your workflow only accepts 'v*.*.*' tags."
exit 1;
fi
else
echo "full_tag=unstable" >> $GITHUB_OUTPUT
echo "tags=unstable" >> $GITHUB_OUTPUT
fi
- name: Build docker image
run: docker build --target "$TARGET" --tag "$IMAGE" .
- name: Basic container runtime test
run: docker run --rm "$IMAGE" -- --help
- name: Save image to disk
run: docker save "$IMAGE" | gzip > image.tar.gz
- name: Creating unique artifact name
id: artifact-name
run: echo "name=${{ github.sha }}-${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
- name: Upload build artifact
uses: actions/upload-artifact@v6.0.0
with:
name: ${{ steps.artifact-name.outputs.name }}
if-no-files-found: 'error'
retention-days: 1
include-hidden-files: true
path: image.tar.gz
deploy:
name: Deploy to ${{ matrix.name }}
environment: ${{ matrix.environment }}
runs-on: ubuntu-latest
needs: build
strategy:
matrix:
include:
- name: GitHub Container Registry
server: ghcr.io
environment: ${{ github.ref_type == 'tag' && 'production' || 'staging' }}-ghcr
username: ${{ github.actor }}
repository: ${{ github.event.repository.name }}
password: GITHUB_TOKEN
fail-fast: true
permissions:
contents: read
packages: write
env:
SERVER: ${{ matrix.server }}
REPO: ${{ github.event.repository.name }}
USER: ${{ matrix.username }}
steps:
- name: Download build artifact
uses: actions/download-artifact@v7.0.0
with: { name: "${{ needs.build.outputs.artifact_name }}" }
- name: Load image from disk
run: docker load < image.tar.gz
- name: Log in to Container Repository (${{ matrix.server }})
run: docker login "$SERVER" --username "$USER" --password "$PASSWORD"
env: { PASSWORD: "${{ secrets[matrix.password] }}" }
- name: Tag docker image with aliases and push
run: |
for tag in $(echo "${{ needs.build.outputs.tags }}" | tr ',' ' '); do
alias="$SERVER/$USER/$REPO:$tag"
alias="${alias,,}" # images must be lowercase
docker tag "$IMAGE" "$alias"
docker push "$alias"
done
- name: Delete untagged versions on GHCR
if: ${{ matrix.server == 'ghcr.io' }}
env:
PACKAGE: "slyde"
GH_TOKEN: "${{ github.token }}"
run: |
now=$(date +%s)
accept='Accept: application/vnd.github+json'
version='X-GitHub-Api-Version: 2022-11-28'
endpoint="/users/$USER/packages/container/$PACKAGE/versions"
images=$(gh api --header "$accept" --header "$version" "$endpoint")
filter='.[] | select(.metadata.container.tags | length == 0)'
untagged=$(echo "$images" | jq --compact-output "$filter")
for image in $untagged; do # delete all packages without tags
id=$(echo "$image" | jq --raw-output '.id')
updated_at=$(echo "$image" | jq --raw-output '.updated_at')
updated_ts=$(date --date="$updated_at" '+%s')
age_days=$(( (now - updated_ts) / (60*60*24) ))
if [ "$age_days" -ge "7" ]; then
echo "Deleting container by id: $id, and with age: $age_days."
endpoint="/users/$USER/packages/container/$PACKAGE/versions/$id"
gh api --method DELETE --header "$accept" \
--header "$version" "$endpoint"
fi
done