build-jobs: use parallel:matrix instead of copy-pasting job definitions

This has the additional benefit that the job is always defined, and
then we can just add the placeholder as any other job

Part-of: https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/6693
[ci:skip-build]: already built successfully in CI
This commit is contained in:
Pablo Correa Gómez
2025-08-13 12:59:38 +02:00
parent 9ddc0e0cb0
commit 9efda70d16
2 changed files with 57 additions and 67 deletions
+25 -60
View File
@@ -17,20 +17,9 @@ workflow:
rules: rules:
- if: $CI_PIPELINE_SOURCE == "parent_pipeline" - if: $CI_PIPELINE_SOURCE == "parent_pipeline"
{% if archs|length == 0 %}
# Needed because gitlab fails if no jobs are ran:
# - https://gitlab.com/gitlab-org/gitlab/-/issues/368248
# This applies to `when: manual` is used on all jobs.
placeholder:
stage: build
script:
- 'true'
{% endif %}
.build: .build:
# Create jobs, but don't run them unless this is # Create jobs, but do not run them unless this is
# overriden in jobs that extend it # overriden in jobs that extend it
when: manual
stage: build stage: build
interruptible: true interruptible: true
before_script: before_script:
@@ -51,57 +40,28 @@ placeholder:
- keys/ - keys/
timeout: 10 h timeout: 10 h
build-x86_64: build:
{% if ('x86_64' in archs) %}
when: always
{% endif %}
extends: .build extends: .build
script: parallel:
- .ci/build-x86_64.sh matrix:
{% for arch in archs %}
build-x86: - ARCH: {{ arch }}
{% if ('x86' in archs) %} TAG: {{ archtag[arch] }}
when: always {% endfor %}
{% if archs|length == 0 %}
- ARCH: placeholder
TAG: shared
{% endif %} {% endif %}
extends: .build tags:
- $TAG
script: script:
- .ci/build-x86.sh # Needed because gitlab fails if no jobs are ran:
# - https://gitlab.com/gitlab-org/gitlab/-/issues/368248
build-aarch64: {% if archs|length == 0 %}
{% if ('aarch64' in archs) %} - 'true'
when: always {% else %}
- .ci/build-$ARCH.sh
{% endif %} {% endif %}
extends: .build
tags: [arm64]
script:
- .ci/build-aarch64.sh
build-armv7:
{% if ('armv7' in archs) %}
when: always
{% endif %}
extends: .build
tags: [qemu]
script:
- .ci/build-armv7.sh
build-armhf:
{% if ('armhf' in archs) %}
when: always
{% endif %}
extends: .build
tags: [qemu]
script:
- .ci/build-armhf.sh
build-riscv64:
{% if ('riscv64' in archs) %}
when: always
{% endif %}
extends: .build
tags: [qemu]
script:
- .ci/build-riscv64.sh
# Hardware testing # Hardware testing
@@ -139,7 +99,12 @@ prepare-{{ device.name }}:
- {{ kernel }} - {{ kernel }}
{%- endfor %} {%- endfor %}
{%- endif %} {%- endif %}
needs: ["build-{{ device.arch }}"] needs:
- job: "build"
parallel:
matrix:
- ARCH: "{{ device.arch }}"
TAG: "{{ archtag[device.arch] }}"
variables: variables:
DEVICE_NAME: {{ device.name }} DEVICE_NAME: {{ device.name }}
# NOTE: All the packages that may influence testing should have an # NOTE: All the packages that may influence testing should have an
+32 -7
View File
@@ -141,6 +141,23 @@ class Device:
return supported_devices return supported_devices
class ArchTagSet(set):
supported_arches = [
Arch.x86_64,
Arch.x86,
Arch.aarch64,
Arch.armv7,
Arch.armhf,
Arch.riscv64,
]
def update(self, iterable):
# This ignores things like !armv7, that could be a follow-up optimization
if 'noarch' in iterable or 'all' in iterable:
iterable = [arch for arch in self.supported_arches]
super().update([Arch(arch) for arch in iterable if Arch(arch) in self.supported_arches])
if __name__ == "__main__": if __name__ == "__main__":
# Needs input to output if we should create the jobs # Needs input to output if we should create the jobs
if len(sys.argv) != 3: if len(sys.argv) != 3:
@@ -163,7 +180,7 @@ if __name__ == "__main__":
# Get the list of supported devices # Get the list of supported devices
supported_devices = Device.supported_devices() supported_devices = Device.supported_devices()
archs = set() archs = ArchTagSet()
devices_under_test = set() devices_under_test = set()
packages_modified = set() packages_modified = set()
# Get and print modified packages # Get and print modified packages
@@ -189,19 +206,27 @@ if __name__ == "__main__":
if apkbuild['pkgname'] in device.dependencies: if apkbuild['pkgname'] in device.dependencies:
devices_under_test.add(device) devices_under_test.add(device)
# This ignores things like !armv7, that could be a follow-up optimization
if 'noarch' in archs or 'all' in archs:
archs = set([str(arch) for arch in Arch.supported()])
if common.commit_message_has_string("[ci:skip-build]"): if common.commit_message_has_string("[ci:skip-build]"):
print("User requested skipping build, not creating child pipeline file") print("User requested skipping build, not creating child pipeline file")
archs = set() archs = ArchTagSet()
devices_under_test = set() devices_under_test = set()
print(f"Architectures to build: {archs}") print(f"Architectures to build: {archs}")
print(f"Devices under test: {devices_under_test}") print(f"Devices under test: {devices_under_test}")
with open(template) as f: with open(template) as f:
rendered = Template(f.read()).render(archs=archs, devices_under_test=devices_under_test, packages_modified=packages_modified) rendered = Template(f.read()).render(
archs=archs,
devices_under_test=devices_under_test,
packages_modified=packages_modified,
archtag={
Arch.x86_64: "shared",
Arch.x86: "shared",
Arch.aarch64: "arm64",
Arch.armv7: "qemu",
Arch.armhf: "qemu",
Arch.riscv64: "qemu",
},
)
with open(child_pipeline, "w") as fw: with open(child_pipeline, "w") as fw:
fw.write(rendered) fw.write(rendered)