Do not abort the jobs when nounset is enabled

The job scripts expanded the optional GITLAB_TOFU_VAR_FILES without a default:

if [ -z "${GITLAB_TOFU_VAR_FILES}" ]; then

A before_script that enables set -u therefore terminated validate, plan and the other affected jobs before gitlab-tofu was ever invoked. This regressed in 4.8.0 with !537 (merged), which replaced the unconditional assignment with a guard so that the variable can overwrite the var_files input. All ten templates carrying that block are fixed to use ${GITLAB_TOFU_VAR_FILES:-}.

plan had the same defect on a second variable that the issue does not mention:

if [ -n "${CI_MERGE_REQUEST_ID}" ]; then

GitLab does not inject CI_MERGE_REQUEST_ID outside of merge request pipelines, so with post_mr_plan_comment enabled the plan job would have died on a branch pipeline even after the var files fix. The equivalent check in policy-enforcement gates on CI_PIPELINE_SOURCE, which is always set, and needs no change.

The second commit hardens the same pattern in the deprecated OCI_REGISTRY* warning in module-release, provider-release and publish-policy-bundle. Reaching it requires replacing the before_script those jobs define, which removes the check along with the tool installation, so it was not reachable in practice. It is fixed anyway, so that no expansion of an optional variable in the templates depends on nounset being off.

Testing

The VarFiles integration test now enables nounset for all of its jobs. It already runs with var_files set and GITLAB_TOFU_VAR_FILES unset, which is exactly the condition that failed, and it covers fmt, validate, test, plan, apply, destroy and delete-state, so it costs no extra CI time.

${var:-} is POSIX parameter expansion (Shell Command Language 2.6.2, Use Default Values), and nounset does not apply to it because the expansion defines a substitution for the unset case. Verified against both base images: busybox ash on alpine, and dash and bash on debian. In all three the pre-fix guard exits non-zero with parameter not set / unbound variable, and the fixed guard falls back correctly for an unset and for an explicitly empty value while preserving a value that is set.

Every remaining shell expansion in every before_script, script and after_script across templates/ was audited. What is left is either a job-level variables entry, a CI variable present in every job, a variable assigned earlier in the same block, or CI_MERGE_REQUEST_IID inside a block already gated on an MR pipeline.

Closes #276 (closed)

Edited by Timo Furrer

Merge request reports

Loading