Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,27 @@ jobs:
size=$(wc -c < target/release/polygo); echo "release binary: $size bytes"
[ "$size" -lt 15728640 ]
time target/release/polygo --help > /dev/null

# GitHub loads action/action.yml before a step runs, and a manifest it cannot parse
# fails every job that uses the Action with a YAML error instead of a polygo message.
# Nothing else here loads it, so this job does: it uses the Action from this checkout.
action:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: A project with a broken translation
run: |
mkdir -p fixture/locales
printf '{\n "greet": "Hi {{name}}"\n}\n' > fixture/locales/en.json
printf '{\n "greet": "Hallo {{nome}}"\n}\n' > fixture/locales/de.json
- id: check
uses: ./action
continue-on-error: true
with:
mode: check
path: fixture/locales
- name: The Action ran and found the placeholder
run: |
[ "${{ steps.check.outcome }}" = failure ] || { echo "the Action should have failed on the error"; exit 1; }
[ "${{ steps.check.outputs.errors }}" = 1 ] || { echo "expected 1 error, got '${{ steps.check.outputs.errors }}'"; exit 1; }
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to polygo. Versions follow [SemVer](https://semver.org); dates are ISO.

## Unreleased

- The GitHub Action's manifest could not be parsed at all: one input description held an unquoted `(default: …)`, which YAML reads as a mapping, so every workflow using `Na5co/polygo/action@v0` failed at "Set up job" with a YAML error before polygo ran. Found by using the Action on a real pull request. Quoted, plus two guards: a test that lints every plain scalar in the manifest for the same trap, and a CI job that uses the Action from this checkout on a fixture and asserts it finds the planted error.

## 0.1.8 — 2026-09-22

- `syntax` (error): a string file that does not parse — a comma dropped from a JSON catalog, an unclosed `<string>`, a file in the wrong encoding — with the line the parser stopped at. It used to be invisible: the detector could not read the file, so the locale disappeared from the run and `check` reported the project as fine. Found while testing the reviewer on a pull request that corrupted a locale file and got a clean review. Every locale file the `locale_path` template matches is scanned, including locales the configuration never lists; when the broken file is one the project must read, the run says so and stops instead of failing with a stack of parser context.
Expand Down
2 changes: 1 addition & 1 deletion action/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ inputs:
description: polygo release to install (tag), or "latest"
default: latest
locales:
description: Comma-separated locales to translate (default: all targets in polygo.toml)
description: "Comma-separated locales to translate (default: all targets in polygo.toml)"
default: ""
args:
description: Extra arguments for `polygo translate` (e.g. --no-context)
Expand Down
42 changes: 42 additions & 0 deletions tests/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,45 @@ fn action_yml_has_a_check_mode() {
assert!(yml.contains(needle), "action.yml lacks {needle}");
}
}

/// The Action's manifest is YAML GitHub has to load before anything runs, and a broken one
/// fails every job that uses it with a parser error rather than a polygo message. polygo's
/// own CI never loads it, so it is linted here instead: a plain scalar holding `: ` (a
/// description with a parenthetical, say) is read as a mapping and breaks the file.
#[test]
fn action_manifest_is_loadable_yaml() {
let text = fs::read_to_string(
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("action/action.yml"),
)
.unwrap();
let mut bad = Vec::new();
for (n, line) in text.lines().enumerate() {
let Some((key, value)) = line.split_once(": ") else {
continue;
};
let key = key.trim();
if !matches!(key, "description" | "default" | "value" | "name" | "title") {
continue;
}
let value = value.trim();
let quoted = (value.starts_with('"') && value.ends_with('"'))
|| (value.starts_with('\'') && value.ends_with('\''))
|| value.starts_with("${{")
|| value.starts_with('|');
if !quoted && (value.contains(": ") || value.ends_with(':')) {
bad.push(format!("{}: {line}", n + 1));
}
}
assert!(
bad.is_empty(),
"action.yml has {} value(s) YAML reads as a mapping; quote them:\n{}",
bad.len(),
bad.join("\n")
);
// The inputs the README and the tests rely on are all there.
for input in [
"mode", "path", "strict", "sarif", "review", "version", "token",
] {
assert!(text.contains(&format!("\n {input}:")), "no {input} input");
}
}
3 changes: 3 additions & 0 deletions tests/release_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ fn release_assets_match_every_consumer() {
"{ci}"
);
assert!(ci.contains("cargo test --workspace"), "{ci}");
// A job that actually loads action/action.yml: a manifest GitHub cannot parse fails
// every job that uses the Action, and nothing else in CI reads it.
assert!(ci.contains("uses: ./action"), "{ci}");
// The formula is generated, not checked in.
assert!(!std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/packaging")).exists());
}
Expand Down
Loading