-
Notifications
You must be signed in to change notification settings - Fork 1
190 lines (170 loc) · 7.34 KB
/
create_packages.yml
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
---
name: Create packages
on:
push:
tags:
- "v*" # Trigger on version tags
branches:
- "main"
- "master"
- "develop"
- "production"
- "test-prod"
paths-ignore:
- "**.md"
- "docs/**"
- ".gitignore"
- "LICENSE"
jobs:
changes:
runs-on: ubuntu-latest
outputs:
frontend: ${{ steps.filter.outputs.frontend }}
main: ${{ steps.filter.outputs.main }}
r-api: ${{ steps.filter.outputs.r-api }}
steps:
- uses: actions/checkout@v3
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
frontend:
- 'frontend/**'
- '.docker/frontend'
main:
- 'app/**'
- '.docker/main'
r-api:
- 'R/**'
- '.docker/r-api'
build:
needs: changes
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Update tags.json version
uses: jossef/[email protected]
with:
file: frontend/src/tags.json
field: gitBranch
value: ${{ github.ref_name }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USER }}
password: ${{ secrets.GHCR_PAT }}
- name: Prepare .docker files
run: |
for p in .docker/*.default ; do
mv "$p" "${p%.default}"
done
# Pull existing images for layer caching
- name: Pull existing images
run: |
# Sanitize branch name for docker tags
branch="${{ github.ref_name }}"
safe_branch="${branch//\//-}" # Replace / with -
for image in herdbook_r-api herdbook_main herdbook_frontend; do
docker pull "ghcr.io/nbisweden/$image:latest" || true
docker pull "ghcr.io/nbisweden/$image:$safe_branch" || true
done
# Build images using docker compose
- name: Build images
env:
DOCKER_BUILDKIT: 1
COMPOSE_DOCKER_CLI_BUILD: 1
run: |
# For tags, we rebuild frontend and main with the correct version
# For production, we build fresh
# For other branches, we build only changed components
if [[ "${{ github.ref_type }}" == "tag" ]]; then
echo "Tag detected - rebuilding frontend and main with version ${{ github.ref_name }}"
# Pull production image for r-api
docker pull "ghcr.io/nbisweden/herdbook_r-api:production"
# Build frontend and main with new version
docker compose build --build-arg BUILDKIT_INLINE_CACHE=1 \
--build-arg COMMIT_SHA="${{ github.sha }}" \
herdbook-frontend main
elif [[ "${{ github.ref_name }}" == "production" ]]; then
echo "Production branch - building fresh images"
docker compose build --no-cache --build-arg BUILDKIT_INLINE_CACHE=1 \
--build-arg COMMIT_SHA="${{ github.sha }}" \
herdbook-frontend main
else
# For other branches, only build changed images and their dependents
if [[ "${{ needs.changes.outputs.frontend }}" == "true" ]]; then
docker compose build --build-arg BUILDKIT_INLINE_CACHE=1 \
--build-arg COMMIT_SHA="${{ github.sha }}" \
herdbook-frontend main
elif [[ "${{ needs.changes.outputs.main }}" == "true" ]]; then
docker compose build --build-arg BUILDKIT_INLINE_CACHE=1 \
--build-arg COMMIT_SHA="${{ github.sha }}" \
main
fi
if [[ "${{ needs.changes.outputs.r-api }}" == "true" ]]; then
docker compose build --build-arg BUILDKIT_INLINE_CACHE=1 r-api
fi
fi
# Push images
- name: Push images
run: |
# Sanitize branch name for docker tags
branch="${{ github.ref_name }}"
safe_branch="${branch//\//-}" # Replace / with -
# Function to push an image if it was built or if we're tagging
push_if_built() {
local image="$1"
local is_tag="${2:-false}"
# For tags, try to pull the production image first and verify commit SHA
if [[ "$is_tag" == "true" ]]; then
echo "Pulling production image for $image..."
docker pull "ghcr.io/nbisweden/$image:production" || { echo "Failed to pull production image"; return 1; }
# Extract commit SHA from production image label
prod_sha=$(docker inspect "ghcr.io/nbisweden/$image:production" --format '{{index .Config.Labels "org.opencontainers.image.revision"}}')
current_sha="${{ github.sha }}"
echo "Production image commit: $prod_sha"
echo "Tag commit: $current_sha"
if [[ "$prod_sha" != "$current_sha" ]]; then
echo "Error: Production image was not built from the same commit as this tag"
echo "Production commit: $prod_sha"
echo "Tag commit: $current_sha"
return 1
fi
docker tag "ghcr.io/nbisweden/$image:production" "$image:latest"
fi
if docker image inspect "$image:latest" >/dev/null 2>&1; then
docker tag "$image:latest" "ghcr.io/nbisweden/$image:$safe_branch"
docker push "ghcr.io/nbisweden/$image:$safe_branch"
if [[ "${{ github.ref_type }}" == "tag" || "$branch" == "main" || "$branch" == "master" || "$branch" == "develop" || "$branch" == "production" || "$branch" == "test-prod" ]]; then
docker tag "$image:latest" "ghcr.io/nbisweden/$image:latest"
docker push "ghcr.io/nbisweden/$image:latest"
fi
fi
}
# For tags, retag production images. For production, push built images
if [[ "${{ github.ref_type }}" == "tag" ]]; then
# Frontend and main were rebuilt with new version
push_if_built "herdbook_frontend"
push_if_built "herdbook_main"
# R-API uses production image
docker tag "ghcr.io/nbisweden/herdbook_r-api:production" "ghcr.io/nbisweden/herdbook_r-api:$safe_branch"
docker tag "ghcr.io/nbisweden/herdbook_r-api:production" "ghcr.io/nbisweden/herdbook_r-api:latest"
docker push "ghcr.io/nbisweden/herdbook_r-api:$safe_branch"
docker push "ghcr.io/nbisweden/herdbook_r-api:latest"
elif [[ "${{ github.ref_name }}" == "production" ]]; then
push_if_built "herdbook_frontend"
push_if_built "herdbook_main"
else
# For other branches, push only the images that were built
if [[ "${{ needs.changes.outputs.frontend }}" == "true" ]]; then
push_if_built "herdbook_frontend"
fi
if [[ "${{ needs.changes.outputs.main }}" == "true" || "${{ needs.changes.outputs.frontend }}" == "true" ]]; then
push_if_built "herdbook_main"
fi
if [[ "${{ needs.changes.outputs.r-api }}" == "true" ]]; then
push_if_built "herdbook_r-api"
fi
fi