Flatten YAML anchor aliases that expand to arrays in script fields
What
Anchor aliases used inside script: / before_script: / after_script: (the documented GitLab "YAML anchors for scripts" optimization) expand to a nested []any element after YAML parsing. toStringList kept only string elements, so every aliased step was silently dropped from the compiled job script.
This broke the Drupal contrib templates (project/gitlab_templates): the *get-utility-files step that downloads get-file-via-curl.sh vanished, so the job later failed with get-file-via-curl.sh: No such file or directory — while the same pipeline passed on git.drupalcode.org.
How
Add toScriptList/getScriptList that recursively flatten nested arrays, mirroring GitLab's Entry::Commands (Array(@config).flatten in lib/gitlab/ci/config/entry/commands.rb).
Scoping: flattening is applied to exactly the Entry::Commands fields — script, before_script, after_script, hooks:pre_get_sources_script, and services:command. toStringList stays string-only for tags / dependencies / paths / entrypoint / etc., because GitLab validates those as array_of_strings and errors on nested input rather than flattening it. (The plan left "shared vs scoped" open; scoped is the higher-fidelity match.)
Non-string scalars in a script list are still dropped, matching the previous behavior.
Tests
- Unit:
toScriptList(flatten incl. deep nesting + scalar drop) andtoStringList(locks in no-flatten). - Integration (
ParseMergedYAML): anchor aliases inscript/before_script,hooks:pre_get_sources_script, both service-command paths, and a negative test provingtagsis not flattened.
Verification
go build ./...,go vet ./...,make test,make test-e2e-parse,make test-e2e-golden— all pass.- Real reproduction:
glci run composeron a Drupal module checkout (clean daemon + cleared include cache). The*get-utility-filesstep now executes, the job gets pastsource $CI_PROJECT_DIR/get-file-via-curl.sh scripts/expand_composer_json.php, and the pipeline passes.
Notes
- The comprehensive e2e fixture was intentionally not extended: the golden comparison checks pipeline structure (names/stages/needs/when), not script content, so an anchor job there would not guard this fix. The unit/integration tests and the real Drupal run are the meaningful coverage.
- A related secondary issue (inspection commands
glci show/jobs/variablesresolving includes before loading.glci.env, causing a 404) is left for a separate follow-up MR.
Closes #103 (closed)