mirror of
https://github.com/MeshTender/MeshTender.git
synced 2026-09-02 01:38:17 +00:00
Fix failing woodpecker pipeline
This commit is contained in:
+12
-4
@@ -109,10 +109,18 @@ steps:
|
||||
deploy:
|
||||
image: alpine/kubectl:1.35.3
|
||||
commands:
|
||||
# No ${...} around shell variables anywhere in this step: Woodpecker does
|
||||
# its own ${VAR} substitution before the shell runs, so "${IMAGE##*@}"
|
||||
# would be replaced with an empty string rather than reaching bash. $(…)
|
||||
# and bare $VAR are untouched, so the digest is cut with a command instead.
|
||||
# Shell variables stay bare ($IMAGE, never brace-wrapped): Woodpecker runs
|
||||
# its own substitution over this file before the shell sees it, and it
|
||||
# replaces a brace-wrapped name with the CI value — empty, for a variable
|
||||
# only the shell knows. $(…) and bare $VAR are passed through untouched, so
|
||||
# the digest is cut with a command rather than a brace expansion.
|
||||
#
|
||||
# That substitution reads the whole file, comments included, and rejects
|
||||
# anything brace-wrapped that isn't a valid variable name — which is why
|
||||
# this comment describes the trap instead of quoting it. A malformed one
|
||||
# fails the pipeline before any step runs, with "unable to parse variable
|
||||
# name" and no indication of where. TestWoodpeckerVariablesAreParseable
|
||||
# catches it locally instead.
|
||||
- IMAGE="$(cat image-ref)"
|
||||
- DIGEST="$(cut -d@ -f2 image-ref)"
|
||||
# Fail loudly rather than deploying with an empty/garbled digest: the app
|
||||
|
||||
@@ -273,3 +273,43 @@ func TestImageDigestEnvVarMatchesConfig(t *testing.T) {
|
||||
t.Errorf(".woodpecker/build.yaml does not set %s, the variable internal/config reads", name)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWoodpeckerVariablesAreParseable catches a failure with an unusually bad
|
||||
// signal-to-effort ratio: Woodpecker substitutes variables over the RAW pipeline
|
||||
// file — comments included — before parsing any YAML. A brace-wrapped token that
|
||||
// isn't a valid variable name kills the whole pipeline with "unable to parse
|
||||
// variable name", naming neither the file nor the line, and no step ever runs. A
|
||||
// comment that merely *describes* the syntax is enough to trigger it.
|
||||
//
|
||||
// So: every ${…} in .woodpecker must open with something that could actually be
|
||||
// a variable name. Bash operators after the name (${VAR##glob}, ${VAR:-default})
|
||||
// are fine — only the name itself is checked.
|
||||
func TestWoodpeckerVariablesAreParseable(t *testing.T) {
|
||||
root := repoRoot(t)
|
||||
entries, err := os.ReadDir(filepath.Join(root, ".woodpecker"))
|
||||
if err != nil {
|
||||
t.Fatalf("read .woodpecker: %v", err)
|
||||
}
|
||||
|
||||
braced := regexp.MustCompile(`\$\{([^}]*)\}`)
|
||||
validName := regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*`)
|
||||
checked := 0
|
||||
for _, e := range entries {
|
||||
if e.IsDir() || !strings.HasSuffix(e.Name(), ".yaml") {
|
||||
continue
|
||||
}
|
||||
rel := filepath.Join(".woodpecker", e.Name())
|
||||
body := readRepoFile(t, rel)
|
||||
for _, m := range braced.FindAllStringSubmatch(body, -1) {
|
||||
checked++
|
||||
if !validName.MatchString(m[1]) {
|
||||
t.Errorf("%s: %q is not a parseable variable reference. Woodpecker rejects the "+
|
||||
"whole pipeline for this — including in comments, so describe the syntax "+
|
||||
"rather than quoting it.", rel, m[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
if checked == 0 {
|
||||
t.Error("found no ${...} references in .woodpecker — has the CI layout changed?")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user