mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-03 19:12:00 +10:00
ci: build newly added variants in the PR matrix (#11549)
* ci: build newly added variants in the PR matrix A new board declares board_level = release, so it gets no CI build until after merge. Build the first env of each platformio.ini added by a PR, regardless of board_level. Only added files qualify; adding an env to an existing config does not. * ci: also detect added variants in merge_group runs merge_group uses the same --level pr subset as pull_request, so a newly added variant was skipped there. Derive the diff base from github.event.merge_group.base_sha for those runs. * ci: fail the matrix step when the variant diff errors Process substitution hides the exit status, so a failed diff silently yielded an empty list and dropped the new board from the matrix. Capture into a variable so 'set -e' aborts the step instead.
This commit is contained in:
@@ -55,6 +55,9 @@ jobs:
|
|||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
|
with:
|
||||||
|
# Needed to diff against the base branch for newly added variants.
|
||||||
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@v6
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
@@ -62,11 +65,33 @@ jobs:
|
|||||||
- run: pip install -U platformio
|
- run: pip install -U platformio
|
||||||
- name: Generate matrix
|
- name: Generate matrix
|
||||||
id: jsonStep
|
id: jsonStep
|
||||||
|
env:
|
||||||
|
BASE_REF: ${{ github.base_ref }}
|
||||||
|
MERGE_GROUP_BASE_SHA: ${{ github.event.merge_group.base_sha }}
|
||||||
run: |
|
run: |
|
||||||
|
# A new board is 'release' and gets no CI until after merge, so force-build the
|
||||||
|
# first env of each ADDED variant config. A new env in an existing one does not count.
|
||||||
|
DIFF_BASE=""
|
||||||
|
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
|
||||||
|
git fetch --no-tags --depth=1 origin "$BASE_REF"
|
||||||
|
DIFF_BASE=$(git merge-base FETCH_HEAD HEAD)
|
||||||
|
elif [[ "$GITHUB_EVENT_NAME" == "merge_group" ]]; then
|
||||||
|
DIFF_BASE="$MERGE_GROUP_BASE_SHA"
|
||||||
|
fi
|
||||||
|
ADDED_ARGS=()
|
||||||
|
if [[ -n "$DIFF_BASE" ]]; then
|
||||||
|
# Assign rather than pipe: a failing diff must abort the step under 'set -e',
|
||||||
|
# not silently yield an empty list and drop the new board from the matrix.
|
||||||
|
ADDED_CONFIGS=$(git diff --name-only --diff-filter=A \
|
||||||
|
"$DIFF_BASE" HEAD -- 'variants/**/platformio.ini')
|
||||||
|
while IFS= read -r cfg; do
|
||||||
|
[[ -n "$cfg" ]] && ADDED_ARGS+=(--added-config "$cfg")
|
||||||
|
done <<<"$ADDED_CONFIGS"
|
||||||
|
fi
|
||||||
# PRs and (for now) merge_group builds use the narrowed --level pr board
|
# PRs and (for now) merge_group builds use the narrowed --level pr board
|
||||||
# subset. Full-matrix builds run on push / schedule / workflow_dispatch.
|
# subset. Full-matrix builds run on push / schedule / workflow_dispatch.
|
||||||
if [[ "$GITHUB_EVENT_NAME" == "pull_request" || "$GITHUB_EVENT_NAME" == "merge_group" ]]; then
|
if [[ "$GITHUB_EVENT_NAME" == "pull_request" || "$GITHUB_EVENT_NAME" == "merge_group" ]]; then
|
||||||
TARGETS=$(./bin/generate_ci_matrix.py all --level pr)
|
TARGETS=$(./bin/generate_ci_matrix.py all --level pr "${ADDED_ARGS[@]}")
|
||||||
else
|
else
|
||||||
TARGETS=$(./bin/generate_ci_matrix.py all)
|
TARGETS=$(./bin/generate_ci_matrix.py all)
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -23,10 +23,29 @@ parser.add_argument(
|
|||||||
default=[],
|
default=[],
|
||||||
help="Board level to build for (omit for the 'pr' + 'release' matrix)",
|
help="Board level to build for (omit for the 'pr' + 'release' matrix)",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--added-config",
|
||||||
|
action="append",
|
||||||
|
default=[],
|
||||||
|
metavar="PATH",
|
||||||
|
help="platformio.ini added by this PR; its first env is built regardless of board_level",
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
outlist = []
|
outlist = []
|
||||||
|
|
||||||
|
# A brand-new board is normally 'release', so it would get no CI until after merge.
|
||||||
|
# Build the first env of each newly added config so it is compiled at least once.
|
||||||
|
forced_envs = set()
|
||||||
|
for added_path in args.added_config:
|
||||||
|
try:
|
||||||
|
with open(added_path, encoding="utf-8") as added_file:
|
||||||
|
first_env = re.search(r"^[ \t]*\[env:([^\]]+)\]", added_file.read(), re.MULTILINE)
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
if first_env:
|
||||||
|
forced_envs.add(first_env.group(1).strip())
|
||||||
|
|
||||||
cfg = ProjectConfig.get_instance()
|
cfg = ProjectConfig.get_instance()
|
||||||
pio_envs = cfg.envs()
|
pio_envs = cfg.envs()
|
||||||
|
|
||||||
@@ -69,6 +88,9 @@ for env in all_envs:
|
|||||||
# Always include board_level = 'pr'
|
# Always include board_level = 'pr'
|
||||||
if env["board_level"] == "pr":
|
if env["board_level"] == "pr":
|
||||||
outlist.append(env["ci"])
|
outlist.append(env["ci"])
|
||||||
|
# Include the first env of a platformio.ini added by this PR
|
||||||
|
elif env["ci"]["board"] in forced_envs:
|
||||||
|
outlist.append(env["ci"])
|
||||||
# Include board_level = 'extra' when requested
|
# Include board_level = 'extra' when requested
|
||||||
elif "extra" in args.level and env["board_level"] == "extra":
|
elif "extra" in args.level and env["board_level"] == "extra":
|
||||||
outlist.append(env["ci"])
|
outlist.append(env["ci"])
|
||||||
|
|||||||
Reference in New Issue
Block a user