Skip to content

Commit b8f1ceb

Browse files
committed
feat: replace GitHub weblog base image build with a poll for GitLab's push
GitHub Actions has no dependency mechanism on GitLab CI jobs, so instead of building weblog base images itself (via the removed, already-broken utils/script/build_base_image.py and PR labels), it now waits for the tag declared in the weblog's Dockerfile to be pushed by GitLab's build_base_images job, polling Docker Hub every 30s with a 15 minute timeout (utils/scripts/wait_for_base_image.py). Drops the _build_weblog_base_images label-gated flag entirely: waiting is cheap (a single manifest inspect when the tag already exists) so it now runs unconditionally for every weblog that has a base image tag.
1 parent 0797a09 commit b8f1ceb

13 files changed

Lines changed: 117 additions & 124 deletions

File tree

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ jobs:
8686
_build_buddies_images: ${{ contains(github.event.pull_request.labels.*.name, 'build-buddies-images') }}
8787
_build_lambda_proxy_image: ${{ fromJson(needs.compute_libraries_and_scenarios.outputs.rebuild_lambda_proxy) }}
8888
_build_proxy_image: ${{ contains(github.event.pull_request.labels.*.name, 'build-proxy-image') }}
89-
_build_weblog_base_images: ${{ contains(github.event.pull_request.labels.*.name, 'build-python-base-images') && matrix.library == 'python' || contains(github.event.pull_request.labels.*.name, 'build-php-base-images') && matrix.library == 'php' || contains(github.event.pull_request.labels.*.name, 'build-nodejs-base-images') && matrix.library == 'nodejs' }}
9089
_enable_replay_scenarios: true
9190
_system_tests_dev_mode: ${{ matrix.version == 'dev' }}
9291
_system_tests_library_target_branch_map: ${{ needs.compute_libraries_and_scenarios.outputs.target-branch-map }}

.github/workflows/compute-workflow-parameters.yml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@ on:
5252
default: ''
5353
required: false
5454
type: string
55-
_build_weblog_base_images:
56-
description: "Shall we build weblog base images"
57-
default: false
58-
required: false
59-
type: boolean
6055

6156
# Map the workflow outputs to job outputs
6257
outputs:
@@ -142,7 +137,6 @@ jobs:
142137
--parametric-job-count ${{ inputs.parametric_job_count }} \
143138
--explicit-binaries-artifact "${{ inputs.binaries_artifact }}" \
144139
--system-tests-dev-mode "${{ inputs._system_tests_dev_mode }}" \
145-
--build-weblog-base-images "${{ inputs._build_weblog_base_images }}" \
146140
--output $GITHUB_OUTPUT
147141
- name: log
148142
run: |
@@ -156,7 +150,6 @@ jobs:
156150
--parametric-job-count ${{ inputs.parametric_job_count }} \
157151
--explicit-binaries-artifact "${{ inputs.binaries_artifact }}" \
158152
--system-tests-dev-mode "${{ inputs._system_tests_dev_mode }}" \
159-
--build-weblog-base-images "${{ inputs._build_weblog_base_images }}" \
160153
--format json | jq
161154
162155
- name: Extract library target branch

.github/workflows/run-end-to-end.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ on:
6363
required: false
6464
type: boolean
6565
_build_weblog_base_image:
66-
description: "Shall we build the weblog base image (only valid if weblog build is local)"
66+
description: "Shall we wait for the weblog base image to be pushed by GitLab CI before building the weblog"
6767
default: false
6868
required: false
6969
type: boolean
@@ -146,11 +146,9 @@ jobs:
146146
if: inputs._build_lambda_proxy_image
147147
run: ./build.sh -i lambda-proxy
148148

149-
- name: Build weblog base image
149+
- name: Wait for weblog base image
150150
if: inputs._build_weblog_base_image
151-
run: |
152-
source venv/bin/activate
153-
./utils/script/build_base_image.py ${{ inputs.library }} ${{ inputs.weblog }}
151+
run: python3 ./utils/scripts/wait_for_base_image.py ${{ inputs.library }} ${{ inputs.weblog }} --timeout 900 --poll-interval 30
154152

155153
- name: Pull images
156154
uses: ./.github/actions/pull_images

.github/workflows/system-tests.yml

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@ on:
4444
default: 'custom'
4545
required: false
4646
type: string
47-
_build_weblog_base_images:
48-
description: "Shall we rebuild weblog base images"
49-
default: false
50-
required: false
51-
type: boolean
5247
_build_buddies_images:
5348
description: "Shall we build buddies images"
5449
default: false
@@ -154,7 +149,6 @@ jobs:
154149
binaries_artifact: ${{ inputs.binaries_artifact }}
155150
_system_tests_dev_mode: ${{ inputs._system_tests_dev_mode }}
156151
_system_tests_library_target_branch_map: ${{ inputs._system_tests_library_target_branch_map }}
157-
_build_weblog_base_images: ${{ inputs._build_weblog_base_images }}
158152

159153
parametric:
160154
needs:
@@ -215,11 +209,9 @@ jobs:
215209
run: ls -la binaries/
216210
- name: Export github token to a file
217211
run: echo "${{ secrets.GITHUB_TOKEN }}" > "$RUNNER_TEMP/github_token.txt"
218-
- name: Build weblog base images
219-
if: matrix.weblog.build_base_image
220-
run: |
221-
source venv/bin/activate
222-
./utils/script/build_base_image.py ${{ inputs.library }} ${{ matrix.weblog.name }}
212+
- name: Wait for weblog base image
213+
if: matrix.weblog.build_weblog_base_image
214+
run: python3 ./utils/scripts/wait_for_base_image.py ${{ inputs.library }} ${{ matrix.weblog.name }} --timeout 900 --poll-interval 30
223215
- name: Build weblog
224216
id: build
225217
run: SYSTEM_TEST_BUILD_ATTEMPTS=3 ./build.sh ${{ inputs.library }} -i weblog -w ${{ matrix.weblog.name }} -s --github-token-file "$RUNNER_TEMP/github_token.txt"

docs/CI/github-actions.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,4 @@ Those parameters are used only by system-tests own CI
100100
| `_build_buddies_images` | Shall we build buddies images | boolean | false | false |
101101
| `_build_proxy_image` | Shall we build proxy image | boolean | false | false |
102102
| `_build_lambda_proxy_image` | Shall we build the lambda-proxy image | boolean | false | false |
103-
| `_build_weblog_base_images` | Shall we build weblog base images | boolean | false | false |
104103
| `_enable_replay_scenarios` | Enable replay scenarios, should only be used in system-tests CI | boolean | false | false |

docs/edit/update-docker-images.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
Some of images used in system-tests are prebuild and used threw [hub.docker.com/datadog/system-tests](https://hub.docker.com/repository/docker/datadog/system-tests/).
22

3-
If you need to update them, you will need to follow those
3+
For weblog base images (nodejs, python, php), the build and push are fully automated:
44

5-
1. update the version in the tag for the image you've just modified (there should be 3 or 4 occurences in the code)
6-
2. create your PR, and add the relevant label to rebuild the image in the CI
7-
* `build-python-base-images` for python weblogs
8-
* `build-php-base-images` for PHP weblogs
9-
* `build-nodejs-base-images` for Node.js weblogs
10-
* `build-proxy-image` for proxy image
11-
3. just before merging your PR, ping somebody from Reliability & Performance team to push your image to hub.docker.com (`#apm-shared-testing` on slack)
5+
1. GitLab CI's `build_base_images` job (`utils/scripts/build_base_images.py`) runs on every push, on every
6+
branch. For each `docker-bake.hcl` target declared in a library's `weblog_metadata.yml`
7+
`base_image_dependencies` section (see `docs/understand/weblogs/weblog-metadata.md`), it computes a
8+
content hash of the target's dependencies and, if a base image tagged with that hash doesn't already
9+
exist on Docker Hub, builds and pushes it as `<base tag>-<hash>`.
10+
2. If you changed a file listed in `base_image_dependencies`, a new tag will automatically be pushed by
11+
that job. Update the `FROM` line of the relevant weblog Dockerfile(s) to point to the new tag (you can
12+
find it by running `python utils/scripts/build_base_images.py --dry-run` locally).
13+
3. GitHub Actions never builds these images itself: it just waits (polling Docker Hub, with a timeout) for
14+
the tag referenced in the weblog's `FROM` line to become available before building the weblog, via
15+
`utils/scripts/wait_for_base_image.py`. So make sure the GitLab job has had a chance to push the new tag
16+
before (or shortly after) your PR's GitHub CI run starts.
17+
18+
For other prebuilt images (e.g. the proxy image), add the `build-proxy-image` label to your PR to force a
19+
rebuild in GitHub CI; then, just before merging, ping somebody from Reliability & Performance team to push
20+
your image to hub.docker.com (`#apm-shared-testing` on slack).

docs/understand/weblogs/weblog-metadata.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,7 @@ listed paths, then pushes the base image to Docker Hub tagged `<base-tag>-<hash1
6565
doesn't already exist. It never overwrites an existing tag, so weblog Dockerfiles that `FROM` a
6666
base image must have their tag updated by hand after a new one is pushed (run the script with
6767
`--dry-run` to find the current tag for each target).
68+
69+
GitHub Actions never builds these base images itself: `utils/scripts/wait_for_base_image.py`
70+
polls Docker Hub for the tag currently referenced in the weblog's `FROM` line (with a timeout)
71+
before building the weblog, since GitLab CI is the only pipeline that builds and pushes them.

tests/test_the_test/test_ci_orchestrator.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,32 +81,27 @@ def test_weblog_build_mode_is_resolved_from_metadata():
8181
@scenarios.test_the_test
8282
def test_nodejs_build_base_image():
8383
scenario_map = {"endtoend": ["DEFAULT", "INTEGRATION_FRAMEWORKS"]}
84-
defs = get_endtoend_definitions("nodejs", scenario_map, [], "dev", 200000, 256, "123", "", build_base_images=True)
84+
defs = get_endtoend_definitions("nodejs", scenario_map, [], "dev", 200000, 256, "123", "")
8585

8686
assert defs["endtoend_defs"]["parallel_weblogs"] == []
8787

8888
jobs = {job["weblog"]: job for job in defs["endtoend_defs"]["parallel_jobs"]}
8989

90-
# express4 is build_mode=local and has a base Dockerfile → should build base image
90+
# express4 has a base image tag → should wait for it
9191
assert jobs["express4"]["build_weblog_base_image"] is True
9292

93-
# openai-js is build_mode=none and has no base Dockerfile → should not build base image
93+
# openai-js has no base image tag → should not wait for a base image
9494
assert jobs["openai-js@6.0.0"]["build_weblog_base_image"] is False
9595

9696

9797
@scenarios.test_the_test
9898
def test_python_build_base_image():
9999
scenario_map = {"endtoend": ["DEFAULT", "INTEGRATION_FRAMEWORKS"]}
100-
defs = get_endtoend_definitions("python", scenario_map, [], "dev", 200000, 256, "123", "", build_base_images=True)
101-
102-
# all python weblog has build_mode=prebuild. build_weblog_base_image
103-
# only applies to build_mode=local weblogs → should not build base image inline
104-
for job in defs["endtoend_defs"]["parallel_jobs"]:
105-
assert job["build_weblog_base_image"] is False, job
100+
defs = get_endtoend_definitions("python", scenario_map, [], "dev", 200000, 256, "123", "")
106101

107-
# all python weblog with build_mode=prebuild should rebuild base images in the build job
102+
# all python weblogs with a base image tag should wait for it in the build job
108103
for job in defs["endtoend_defs"]["parallel_weblogs"]:
109-
assert job["build_base_images"] is True, job
104+
assert job["build_weblog_base_image"] is True, job
110105

111106

112107
@scenarios.test_the_test

utils/_context/weblog_metadata.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,6 @@ def require_build(self) -> bool:
3333
"""The run_end_to_end job builds the weblog locally (weblog_build_required)."""
3434
return self.build_mode != BuildMode.none
3535

36-
@property
37-
def base_dockerfile(self) -> Path | None:
38-
"""Returns the path of the base image docker file if exists, else None"""
39-
image_name = self.base_image_tag
40-
41-
if image_name is None:
42-
return None
43-
44-
file_prefix = image_name.replace("datadog/system-tests:", "").rsplit("-", 1)[0]
45-
assert file_prefix.endswith(".base")
46-
47-
path = Path(f"utils/build/docker/{self.library}/{file_prefix}.Dockerfile")
48-
return path if path.exists() else None
49-
5036
@property
5137
def base_image_tag(self) -> str | None:
5238
"""system-tests base image tag read from the first FROM in the weblog Dockerfile."""

utils/scripts/build-base-image.py

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)