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
14 changes: 11 additions & 3 deletions .github/tests/cert-expiry/check.bats
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ findings() {
}

@test "fail_on_findings false reports findings without failing" {
INPUT_HOSTS="localhost:${OK_PORT} localhost:${SOON_PORT}" INPUT_FAIL_ON_FINDINGS=false run bash "$SCRIPT"
INPUT_HOSTS=$'localhost:'"${OK_PORT}"$'\nlocalhost:'"${SOON_PORT}" INPUT_FAIL_ON_FINDINGS=false run bash "$SCRIPT"
[ "$status" -eq 0 ]
[ "$(findings | jq length)" -eq 1 ]
grep -qx "checked=2" "$GITHUB_OUTPUT"
}

@test "never prints certificate or key material" {
INPUT_HOSTS="localhost:${OK_PORT} localhost:${SOON_PORT} localhost:${OLD_PORT}" run bash "$SCRIPT"
INPUT_HOSTS=$'localhost:'"${OK_PORT}"$'\nlocalhost:'"${SOON_PORT}"$'\nlocalhost:'"${OLD_PORT}" run bash "$SCRIPT"
[[ "$output" != *"BEGIN"* ]]
! grep -q "BEGIN" "$GITHUB_OUTPUT" "$GITHUB_STEP_SUMMARY"
}
Expand Down Expand Up @@ -129,7 +129,15 @@ findings() {
}

@test "multi-line hosts: blank lines and comments skipped, duplicates removed" {
INPUT_HOSTS=$'localhost:'"${OK_PORT}"$'\n\n# vanity host unset\nLOCALHOST:'"${OK_PORT}"$', localhost:'"${SOON_PORT}" INPUT_DAYS=1 run bash "$SCRIPT"
INPUT_HOSTS=$'localhost:'"${OK_PORT}"$'\n\n# vanity host unset\nLOCALHOST:'"${OK_PORT}"$'\nlocalhost:'"${SOON_PORT}" INPUT_DAYS=1 run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -qx "checked=2" "$GITHUB_OUTPUT"
}

@test "comma or space separated hosts fail with the one-per-line format" {
for h in "localhost:${OK_PORT}, localhost:${SOON_PORT}" "localhost:${OK_PORT} localhost:${SOON_PORT}"; do
INPUT_HOSTS="$h" run bash "$SCRIPT"
[ "$status" -eq 1 ]
[[ "$output" == *"hosts takes one item per line, or a single value."* ]]
done
}
7 changes: 7 additions & 0 deletions .github/tests/shared/inputs.bats
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ setup() {
done
}

@test "list: error keeps quotes on items with spaces" {
run input_list triggers '["my path/", "other path/"]'
[ "$status" -eq 1 ]
[[ "$output" == *'%0A triggers: |%0A "my path/"%0A "other path/"%0A'* ]]
[ "$(input_list triggers $'"my path/"\n"other path/"')" = $'my path/\nother path/' ]
}

@test "bool, enum and debug" {
[ "$(input_bool dry_run TRUE false)" = true ]
[ "$(input_bool dry_run '' true)" = true ]
Expand Down
20 changes: 12 additions & 8 deletions .github/workflows/.pr-close.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ on:
required: false
type: string
packages:
description: "Space-separated list of packages to promote"
description: "Packages to promote, one per line or a single package"
required: false
type: string
remove_pvc:
required: false
default: data-${{ github.event.repository.name }}-${{ github.event.number }}-bitnami-pg-0
type: string
description: "Comma separated list of PVCs to remove"
description: "PVCs to remove, one per line or a single PVC"

### Usually a bad idea / not recommended
merge_branch:
Expand All @@ -29,7 +29,7 @@ on:
type: string
default: ${{ github.event.repository.default_branch }}
cleanup_name:
description: "Use if template/cleanup name differs from repo; space-separated for multiple names"
description: "Use if template/cleanup name differs from repo; one name per line, or a single name"
type: string
default: ""
organization:
Expand Down Expand Up @@ -78,9 +78,14 @@ jobs:
env:
INPUT_PACKAGES: ${{ inputs.packages }}
run: |
# Convert packages to JSON array for job matrix
read -r -a pkgs <<< "$INPUT_PACKAGES"
echo "packages=$(jq -cn '$ARGS.positional' --args "${pkgs[@]}")" >> "$GITHUB_OUTPUT"
# One package per line, or a single package; outer quotes stripped (same rules as shared/inputs.sh;
# a reusable workflow can't read files from this repository)
packages=$(jq -cRn '[inputs | gsub("^\\s+|\\s+$"; "") | sub("^(?<q>[\"'"'"'])(?<v>.*)\\k<q>$"; "\(.v)") | select(. != "")]' <<< "$INPUT_PACKAGES")
if jq -e 'any(.[]; test("[\\s,;\"'"'"'()\\[\\]]"))' <<< "$packages" > /dev/null; then
echo "::error title=packages: list format::Invalid packages input: ${INPUT_PACKAGES//$'\n'/ }%0Apackages takes one item per line, or a single value.%0AUse:%0A packages: |%0A backend%0A frontend%0AMultiline input syntax: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idstepswith"
exit 1
fi
echo "packages=${packages}" >> "$GITHUB_OUTPUT"

- env:
INPUT_PACKAGES: ${{ inputs.packages }}
Expand All @@ -89,8 +94,7 @@ jobs:
MERGE_BRANCH: ${{ inputs.merge_branch }}
run: |
# Diagnostic vars
read -r -a pkgs <<< "$INPUT_PACKAGES"
echo "packages=$(jq -cn '$ARGS.positional' --args "${pkgs[@]}")"
printf 'packages=%s\n' "${INPUT_PACKAGES//$'\n'/ }"
echo "github.event.pull_request.merged=$PR_MERGED"
echo "github.event.pull_request.base.ref=$PR_BASE_REF"
echo "inputs.merge_branch=$MERGE_BRANCH"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/cert-expiry-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
ref: ${{ steps.base.outputs.sha || github.event.before }}
triggers: |
cert-expiry/
shared/inputs.sh
.github/tests/cert-expiry/
.github/workflows/cert-expiry-tests.yml
!*.md
Expand Down
2 changes: 1 addition & 1 deletion cert-expiry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ To notify only on certificate findings (not on an input error), give the check s

| Input | Default | Description |
| --- | --- | --- |
| `hosts` | required | Hostnames, one per line (commas or spaces also work). `host` or `host:port`, no scheme; port defaults to 443. Blank lines and `#` comments are skipped. |
| `hosts` | required | Hostnames, one per line, or a single host. `host` or `host:port`, no scheme; port defaults to 443. Blank lines and `#` comments are skipped. |
| `days` | `30` | Warn when a certificate expires within this many days. Whole number, 1 to 3650. |
| `timeout` | `10` | Seconds to wait for each handshake. Whole number, 1 to 120. |
| `fail_on_findings` | `true` | Fail the step when any host needs attention, so the next step can notify with `if: failure()`. Outputs are written either way. |
Expand Down
2 changes: 1 addition & 1 deletion cert-expiry/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: "Cert Expiry"
description: "Read-only TLS expiry check: reads each host's public certificate with openssl s_client and reports any that expire within a number of days."
inputs:
hosts:
description: "Hostnames to check, one per line (commas or spaces also work). host or host:port, no scheme. Port defaults to 443. Blank lines and # comments are ignored."
description: "Hostnames to check, one per line, or a single host. host or host:port, no scheme. Port defaults to 443. Blank lines and # comments are ignored."
required: true
days:
description: "Warn when a certificate expires within this many days (whole number, 1 to 3650)."
Expand Down
22 changes: 14 additions & 8 deletions cert-expiry/check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,23 @@ case "$FAIL_ON_FINDINGS" in
*) fail "fail_on_findings must be true or false, got '${FAIL_ON_FINDINGS}'." "Set fail_on_findings: true or fail_on_findings: false." ;;
esac

LIST="$HOSTS"
# Shared list rules (shared/inputs.sh): one host per line, or a single host.
# '# comments' are dropped first.
# shellcheck source=../shared/inputs.sh
source "$(dirname "${BASH_SOURCE[0]}")/../shared/inputs.sh"
COMMENTLESS=""
while IFS= read -r line; do
COMMENTLESS+="${line%%#*}"$'\n'
done <<< "$HOSTS"
LIST="$(input_list hosts "$COMMENTLESS")" || { echo "$LIST"; exit 1; }

# Parse: drop comments, split on commas and whitespace, validate, de-duplicate
# Validate and de-duplicate
LABEL='[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?'
ENTRIES=()
declare -A SEEN=()
while IFS= read -r line; do
line="${line%%#*}"
# read -a splits without pathname expansion, so '*' is rejected, not globbed
IFS=$' \t,' read -r -a parts <<< "$line"
for entry in "${parts[@]}"; do
while IFS= read -r entry; do
[ -n "$entry" ] || continue
{
if [[ "$entry" == *"://"* || "$entry" == */* ]]; then
fail "'${entry}' is a URL, not a hostname." "List the hostname only, for example myapp.gov.bc.ca or myapp.gov.bc.ca:8443."
fi
Expand All @@ -63,7 +69,7 @@ while IFS= read -r line; do
[[ -n "${SEEN[$key]:-}" ]] && continue
SEEN[$key]=1
ENTRIES+=("$key")
done
}
done <<< "$LIST"

((${#ENTRIES[@]} > 0)) || fail "No hostnames to check." "Set hosts to one or more hostnames, one per line."
Expand Down
4 changes: 2 additions & 2 deletions cleanup-pr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ This composite action cleans up resources in a target OpenShift namespace on pul
| Input | Description | Required | Default |
|---|---|---|---|
| `cleanup` | Type of cleanup to run (`helm` or `label`) | No | `label` |
| `cleanup_name` | App labels to delete: one per line, comma separated, or a JSON array (if `cleanup` is `label`). Defaults to `repository-target` | No | `""` |
| `cleanup_name` | App labels to delete: one per line, or a single label (if `cleanup` is `label`). Defaults to `repository-target` | No | `""` |
| `repository` | The GitHub repository name | No | `${{ github.event.repository.name }}` |
| `target` | Environment target identifier (e.g. PR number) | No | `${{ github.event.number }}` |
| `remove_pvc` | PVCs to delete: one per line, comma separated, or a JSON array | No | `""` |
| `remove_pvc` | PVCs to delete: one per line, or a single PVC | No | `""` |
| `oc_server` | OpenShift API server URL with port | Yes | |
| `oc_namespace` | Target OpenShift namespace | **Yes** | N/A |
| `oc_token` | OpenShift Service Account token | **Yes** | N/A |
Expand Down
4 changes: 2 additions & 2 deletions cleanup-pr/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ inputs:
required: false
default: "label"
cleanup_name:
description: "app label values to clean up: one per line, comma separated, or a JSON array (defaults to repository-target)"
description: "app label values to clean up: one per line, or a single value (defaults to repository-target)"
required: false
default: ""
repository:
Expand All @@ -19,7 +19,7 @@ inputs:
required: false
default: ${{ github.event.number }}
remove_pvc:
description: "PVCs to remove: one per line, comma separated, or a JSON array"
description: "PVCs to remove: one per line, or a single PVC"
required: false
default: ""
oc_server:
Expand Down
12 changes: 9 additions & 3 deletions shared/inputs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,21 @@ _input_list_error() {
local name="$1" raw="$2" inner="$2" item
local -a items=()
[[ "$raw" == \(*\) || "$raw" == \[*\] ]] && inner="${raw:1:${#raw}-2}"
for item in ${inner//[,;]/ }; do
item="$(_input_strip_quotes "$item")"
# Tokens: '...' or "..." (spaces kept), else runs without spaces, commas or semicolons
local re="^[[:space:],;]*('[^']*'|\"[^\"]*\"|[^[:space:],;]+)(.*)$"
while [[ "$inner" =~ $re ]]; do
item="$(_input_strip_quotes "${BASH_REMATCH[1]}")"
inner="${BASH_REMATCH[2]}"
[ -n "$item" ] && items+=("$item")
done
[ "${#items[@]}" -gt 0 ] || items=(backend/ frontend/)
local msg="::error title=${name}: list format::Invalid ${name} input: ${raw}"
msg+="%0A${name} takes one item per line, or a single value."
msg+="%0AGot:%0A ${name}: ${raw}%0AUse:%0A ${name}: |"
for item in "${items[@]}"; do msg+="%0A ${item}"; done
# Items with spaces keep their quotes, so the suggested block parses
for item in "${items[@]}"; do
if [[ "$item" =~ [[:space:]] ]]; then msg+="%0A \"${item}\""; else msg+="%0A ${item}"; fi
done
# GitHub's docs on step inputs (with:), including multiline values
msg+="%0AMultiline input syntax: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idstepswith"
echo "$msg"
Expand Down
2 changes: 1 addition & 1 deletion sysdig-monitor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Adding/removing alert recipients is done by editing `spec.team.users[]` in the S
# Default: monitoring/alerts
alerts_dir: monitoring/alerts

# Deployment names: one per line, comma separated, or a JSON array. One alert per file per component.
# Deployment names: one per line, or a single name. One alert per file per component.
# Default: frontend,backend
components: frontend,backend

Expand Down
2 changes: 1 addition & 1 deletion sysdig-monitor/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ inputs:
default: 'monitoring/alerts'
components:
description: |
Deployment names to monitor: one per line, comma separated, or a JSON array.
Deployment names to monitor: one per line, or a single name.
Each component gets one alert per file in alerts_dir.
Example: frontend,backend
default: 'frontend,backend'
Expand Down
Loading