-
Notifications
You must be signed in to change notification settings - Fork 1
LEGLINK-912: Move App Configuration exports to the private link-cac repo #1813
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 2 commits
578cbae
a167adb
14b9a86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,26 +1,28 @@ | ||||||||||||||
| #!/bin/sh | ||||||||||||||
| # | ||||||||||||||
| # Guards the App Configuration exports and the catalog that describes them. | ||||||||||||||
| # Validates the App Configuration catalog: | ||||||||||||||
| # | ||||||||||||||
| # Config/*.json scanned for credentials | ||||||||||||||
| # app-config.yaml validated against its own embedded schema | ||||||||||||||
| # app-config.yaml checked against its own embedded schema | ||||||||||||||
| # | ||||||||||||||
| # The per-environment exports it describes used to be scanned here too. LEGLINK-912 moved them | ||||||||||||||
| # to the private link-cac repository, so nothing under Config/ can be staged in this one any | ||||||||||||||
| # more. That repository has no hook of its own - scanning there would need a clone of this one | ||||||||||||||
| # on every machine - so its CI is what runs validate_aac_secrets.py against them. | ||||||||||||||
| # | ||||||||||||||
| # Enable for your clone with: | ||||||||||||||
| # git config core.hooksPath .githooks | ||||||||||||||
| # | ||||||||||||||
| # Validates the STAGED content, not the working tree, so a problem cannot slip through by | ||||||||||||||
| # being fixed in the file after `git add`. | ||||||||||||||
| # | ||||||||||||||
| # Bypass with `git commit --no-verify`. CI runs the same checks either way. | ||||||||||||||
| # Bypass with `git commit --no-verify`. CI runs the same check either way. | ||||||||||||||
|
|
||||||||||||||
| set -e | ||||||||||||||
|
|
||||||||||||||
| staged_exports=$(git diff --cached --name-only --diff-filter=ACM \ | ||||||||||||||
| | grep -E '^Config/.*\.json$' || true) | ||||||||||||||
| staged_catalog=$(git diff --cached --name-only --diff-filter=ACM \ | ||||||||||||||
| | grep -E '^app-config\.yaml$' || true) | ||||||||||||||
|
|
||||||||||||||
| if [ -z "$staged_exports" ] && [ -z "$staged_catalog" ]; then | ||||||||||||||
| if [ -z "$staged_catalog" ]; then | ||||||||||||||
| exit 0 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -37,59 +39,27 @@ for candidate in python3 python py; do | |||||||||||||
| done | ||||||||||||||
|
|
||||||||||||||
| if [ -z "$PYTHON" ]; then | ||||||||||||||
| echo "pre-commit: no working python found, skipping App Config checks." | ||||||||||||||
| echo "pre-commit: CI will still run them." | ||||||||||||||
| echo "pre-commit: no working python found, skipping the App Config catalog check." | ||||||||||||||
| echo "pre-commit: CI will still run it." | ||||||||||||||
| exit 0 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # Materialize staged blobs so the checks see exactly what is being committed. | ||||||||||||||
| # Materialize the staged blob so the check sees exactly what is being committed. | ||||||||||||||
| tmpdir=$(mktemp -d) | ||||||||||||||
| trap 'rm -rf "$tmpdir"' EXIT | ||||||||||||||
|
|
||||||||||||||
| stage_blob() { | ||||||||||||||
| dest="$tmpdir/$(basename "$1")" | ||||||||||||||
| git show ":$1" > "$dest" | ||||||||||||||
| echo "$dest" | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if [ -n "$staged_exports" ]; then | ||||||||||||||
| files="" | ||||||||||||||
| for path in $staged_exports; do | ||||||||||||||
| files="$files $(stage_blob "$path")" | ||||||||||||||
| done | ||||||||||||||
|
|
||||||||||||||
| # --strict matches appconfig-secret-scan.yml, so the hook cannot pass something CI will | ||||||||||||||
| # reject. Errors block either way; --strict is only about warnings - a secret-shaped key | ||||||||||||||
| # holding a literal, a duplicate (key, label), a malformed entry. Those are worth stopping | ||||||||||||||
| # for here because these files go to a public repository, where a false positive costs a | ||||||||||||||
| # --no-verify and a false negative costs a rotated credential and permanent git history. | ||||||||||||||
| # | ||||||||||||||
| # It does not make the two identical: this scans the staged blob, CI scans all three files | ||||||||||||||
| # on disk. A warning in a file you did not stage still passes here and fails there. | ||||||||||||||
| # shellcheck disable=SC2086 | ||||||||||||||
| if ! "$PYTHON" Scripts/AzureAppConfig/validate_aac_secrets.py --strict $files; then | ||||||||||||||
| echo "" | ||||||||||||||
| echo "pre-commit: BLOCKED -- staged App Config export failed the secret scan." | ||||||||||||||
| echo "pre-commit: An ERROR is a credential: move it into Key Vault and reference it," | ||||||||||||||
| echo "pre-commit: then re-stage. A WARNING is something worth a look rather than" | ||||||||||||||
| echo "pre-commit: certainly wrong; it blocks here because CI runs --strict too." | ||||||||||||||
| echo "pre-commit: If the finding is wrong, commit with --no-verify." | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
| fi | ||||||||||||||
| catalog="$tmpdir/$(basename "$staged_catalog")" | ||||||||||||||
| git show ":$staged_catalog" > "$catalog" | ||||||||||||||
|
|
||||||||||||||
| if [ -n "$staged_catalog" ]; then | ||||||||||||||
| catalog=$(stage_blob "$staged_catalog") | ||||||||||||||
| if ! "$PYTHON" Scripts/AzureAppConfig/validate_app_config_schema.py "$catalog"; then | ||||||||||||||
| echo "" | ||||||||||||||
| echo "pre-commit: BLOCKED -- staged app-config.yaml does not match its own schema." | ||||||||||||||
| echo "pre-commit: Fix the entries above, or commit with --no-verify." | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
| if ! "$PYTHON" Scripts/AzureAppConfig/validate_app_config_schema.py "$catalog"; then | ||||||||||||||
| echo "" | ||||||||||||||
| echo "pre-commit: BLOCKED -- staged app-config.yaml does not match its own schema." | ||||||||||||||
| echo "pre-commit: Fix the entries above, or commit with --no-verify." | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # The required-key check is deliberately NOT run here. It compares the catalog against all | ||||||||||||||
| # three stores, so it would fail on gaps a commit did not introduce and cannot fix. CI reports | ||||||||||||||
| # it instead. | ||||||||||||||
| # The required-key check is deliberately NOT run here. It compares the catalog against every | ||||||||||||||
| # store's export, which now means reading a second repository - and it would fail on gaps a | ||||||||||||||
| # commit did not introduce and cannot fix. Both repositories' CI report it instead. | ||||||||||||||
|
Comment on lines
+61
to
+63
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π Maintainability & Code Quality | π‘ Minor | β‘ Quick win Correct the required-key CI ownership statement. The public workflow now runs unit tests and schema validation only. The PR objective moves required-key checks to Proposed wording fix-# commit did not introduce and cannot fix. Both repositories' CI report it instead.
+# commit did not introduce and cannot fix. The `link-cac` CI reports it instead.π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| exit 0 | ||||||||||||||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π― Functional Correctness | π‘ Minor | β‘ Quick win
Reject a staged deletion of
app-config.yaml.--diff-filter=ACMexcludes deletions. If the catalog is deleted from the index,staged_catalogis empty and Line 26 exits successfully. Detect the deletion and fail before the early return.Proposed fix
π Committable suggestion
π€ Prompt for AI Agents