|
1 | 1 | name: docker |
2 | 2 |
|
3 | | -# run on pushes to main and on tags; adjust to taste |
4 | 3 | on: |
5 | 4 | push: |
6 | 5 | branches: [ main ] |
|
16 | 15 | build-and-push: |
17 | 16 | runs-on: ubuntu-latest |
18 | 17 | env: |
19 | | - # registry to push to. Change to docker.io if you prefer. |
20 | 18 | REGISTRY: docker.io |
21 | | - # owner that will own the pushed images. Defaults to repository owner. |
22 | 19 | OWNER: mrminede |
23 | | - # short commit SHA tag |
24 | 20 | COMMIT_SHORT: ${{ github.sha }} |
25 | 21 | steps: |
26 | 22 | - name: Shorten commit SHA |
|
32 | 28 | with: |
33 | 29 | fetch-depth: 0 |
34 | 30 |
|
35 | | - - name: Set up QEMU (optional for multi-arch builds) |
| 31 | + - name: Set up QEMU |
36 | 32 | uses: docker/setup-qemu-action@v2 |
37 | 33 |
|
38 | 34 | - name: Set up Docker Buildx |
|
44 | 40 | username: ${{ secrets.DOCKERHUB_USERNAME }} |
45 | 41 | password: ${{ secrets.DOCKERHUB_TOKEN }} |
46 | 42 |
|
47 | | - - name: Build all compose services |
48 | | - # uses the Docker Compose CLI shipped with Docker; this runs 'docker compose build' |
49 | | - run: | |
50 | | - docker compose -f docker/docker-compose.yml build --pull |
| 43 | + - name: Build images |
| 44 | + run: docker compose -f docker/docker-compose.yml build --pull |
51 | 45 |
|
52 | | - - name: Tag & push built images |
53 | | - run: | |
54 | | - set -euo pipefail |
55 | | -
|
56 | | - REGISTRY=${{ env.REGISTRY }} |
57 | | - OWNER=${{ env.OWNER }} |
58 | | - SHA=${{ env.COMMIT_SHORT }} |
59 | | - REPO_NAME=${{ github.event.repository.name }} |
60 | | -
|
61 | | - echo "Registry: $REGISTRY" |
62 | | - echo "Owner: $OWNER" |
63 | | - echo "Repo: $REPO_NAME" |
64 | | - echo "Tag: $SHA" |
65 | | -
|
66 | | - # list services defined in compose |
67 | | - services=$(docker compose -f docker/docker-compose.yml config --services) |
68 | | - if [ -z "$services" ]; then |
69 | | - echo "No services found in docker-compose.yml" |
70 | | - exit 1 |
71 | | - fi |
72 | | -
|
73 | | - # decide whether to push 'latest' as well |
74 | | - push_latest=false |
75 | | - if [[ "${GITHUB_REF:-}" == "refs/heads/main" ]] || [[ "${GITHUB_REF:-}" == refs/tags/* ]]; then |
76 | | - push_latest=true |
77 | | - fi |
78 | | -
|
79 | | - for svc in $services; do |
80 | | - echo "Checking service: $svc" |
81 | | -
|
82 | | - # Extract IMAGE and whether a build: exists for this service from 'docker compose config' |
83 | | - svc_info=$(docker compose -f docker/docker-compose.yml config | awk -v svc="$svc" ' |
84 | | - $0 ~ "services:" { in_services=1 } |
85 | | - in_services && $0 ~ "^[[:space:]]*"svc":" { in_svc=1; next } |
86 | | - in_svc && $0 ~ "^[[:space:]]*[^[:space:]]" { exit } |
87 | | - in_svc { |
88 | | - if ($1 == "image:") { gsub(/"/,"",$2); print "IMAGE="$2 } |
89 | | - if ($1 == "build:") { print "HASBUILD=1" } |
90 | | - } |
91 | | - ') |
92 | | -
|
93 | | - # evaluate the small KEY=VAL output (safe in CI) |
94 | | - unset IMAGE HASBUILD |
95 | | - eval "$svc_info" || true |
96 | | -
|
97 | | - # only process services that have both build: and image: |
98 | | - if [ -z "${IMAGE:-}" ] || [ -z "${HASBUILD:-}" ]; then |
99 | | - echo "Skipping $svc (requires both build: and image:)." |
100 | | - continue |
101 | | - fi |
102 | | -
|
103 | | - echo "Service $svc has build and image -> $IMAGE" |
104 | | -
|
105 | | - # determine source reference for tagging: prefer compose image id, then image:latest, then image (no tag) |
106 | | - src_ref="" |
107 | | - imgid=$(docker compose -f docker/docker-compose.yml images -q "$svc" 2>/dev/null || true) |
108 | | - if [ -n "$imgid" ]; then |
109 | | - src_ref="$imgid" |
110 | | - elif docker image inspect "$IMAGE:latest" >/dev/null 2>&1; then |
111 | | - src_ref="$IMAGE:latest" |
112 | | - elif docker image inspect "$IMAGE" >/dev/null 2>&1; then |
113 | | - src_ref="$IMAGE" |
114 | | - else |
115 | | - echo "No built image found for $svc (expected $IMAGE). Did the build step succeed?" |
116 | | - exit 1 |
117 | | - fi |
118 | | -
|
119 | | - target="$REGISTRY/$OWNER/${REPO_NAME}-$svc:$SHA" |
120 | | - echo "Tagging $src_ref -> $target" |
121 | | - docker tag "$src_ref" "$target" |
122 | | -
|
123 | | - echo "Pushing $target" |
124 | | - docker push "$target" |
125 | | -
|
126 | | - if [ "$push_latest" = true ]; then |
127 | | - latest_tag="$REGISTRY/$OWNER/${REPO_NAME}-$svc:latest" |
128 | | - echo "Also tagging & pushing latest: $latest_tag" |
129 | | - docker tag "$src_ref" "$latest_tag" |
130 | | - docker push "$latest_tag" |
131 | | - fi |
132 | | -
|
133 | | - # clean up variables for next iteration |
134 | | - unset IMAGE HASBUILD src_ref imgid |
135 | | - done |
136 | | -
|
137 | | - echo "All done. Images pushed." |
138 | | -
|
139 | | - - name: Output pushed images |
140 | | - run: | |
141 | | - echo "Images pushed for commit $COMMIT_SHORT" |
| 46 | + - name: Push images |
| 47 | + run: docker compose -f docker/docker-compose.yml push |
0 commit comments