You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -8,6 +8,7 @@ The repository uses a set of reusable workflows to build and publish Docker imag
8
8
9
9
1.**Build images only when relevant files change** - avoiding unnecessary builds
10
10
2.**Re-tag existing images when no changes occur** - ensuring every commit on `main` has corresponding Docker image tags without rebuilding
11
+
3.**Deterministic build cancellation** - ensuring that when multiple PRs are merged simultaneously on `main`, only the latest commit's workflow runs (see [Deterministic Build Cancellation](#deterministic-build-cancellation))
11
12
12
13
### Architecture Overview
13
14
@@ -17,25 +18,47 @@ The repository uses a set of reusable workflows to build and publish Docker imag
Checks whether the current commit is the latest on the target branch. This enables deterministic build cancellation by allowing workflows to skip execution if a newer commit has been pushed.
55
+
56
+
**How it works:**
57
+
58
+
1. Uses `git ls-remote` to fetch the latest commit SHA from the remote branch
59
+
2. Compares it with the current workflow's commit SHA (`github.sha`)
60
+
3. Outputs `is_latest: true` if they match, `false` otherwise
61
+
39
62
#### `check-changes-for-docker-build.yml`
40
63
41
64
Determines whether a Docker image needs to be rebuilt by checking if relevant files have changed since the last commit that has a published Docker image.
@@ -50,48 +73,116 @@ Determines whether a Docker image needs to be rebuilt by checking if relevant fi
50
73
51
74
Creates a new tag for an existing Docker image without rebuilding it.
52
75
53
-
### Docker Build Workflow Pattern
76
+
### Docker Build Workflow Patterns
54
77
55
-
Each service has its own docker build workflow (e.g., `coprocessor-docker-build.yml`, `kms-connector-docker-build.yml`) that follows this pattern:
78
+
Each service has its own docker build workflow. There are two patterns depending on the number of images built:
79
+
80
+
#### Simple Pattern (Single Image)
81
+
82
+
Used by workflows that build a single image (e.g., `gateway-contracts-docker-build.yml`, `host-contracts-docker-build.yml`, `test-suite-docker-build.yml`). The decision logic is embedded directly in the job `if` conditions:
56
83
57
84
```yaml
58
85
jobs:
59
-
# 1. Check for changes using the reusable workflow
60
-
check-changes-my-service:
86
+
# 1. Check if this is the latest commit (push events only)
Used by workflows that build multiple images (e.g., `coprocessor-docker-build.yml`, `kms-connector-docker-build.yml`). A centralized `build-decisions` job computes the action for each service to avoid duplicating decision logic:
129
+
130
+
```yaml
131
+
jobs:
132
+
# 1. Check if this is the latest commit (push events only)
When multiple PRs are merged to `main` in quick succession, GitHub's concurrency groups cannot guarantee which workflow will "win" - the ordering is arbitrary. This could result in an older commit's workflow completing while a newer commit's workflow gets cancelled.
178
+
179
+
To solve this, the workflows now use a **deterministic cancellation** approach:
180
+
181
+
1.**`is-latest-commit.yml`** checks at runtime if the current commit is still the latest on the branch
182
+
2. If the commit is the latest: proceed with build or retag. If a newer commit exists: skip all work.
183
+
184
+
This is used only if the docker build workflow is triggered by a push on `main`!
185
+
186
+
This ensures that only the workflow for the most recent commit on `main` will actually build or retag images, regardless of the order in which GitHub starts the workflows.
187
+
188
+
**Note:** Concurrency groups are still used on individual build jobs to prevent duplicate builds of the same service, but the `is-latest-commit` check handles the cross-workflow coordination.
0 commit comments