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
22 changes: 22 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ jobs:
set -o pipefail
swift test 2>&1 | tee /tmp/swift-test.log

- name: Run acceptance smoke tests (capture log)
run: |
set -o pipefail
./scripts/acceptance-tests.sh 2>&1 | tee /tmp/acceptance.log

- name: Convert acceptance output to JUnit
if: always()
run: |
./scripts/acceptance-to-junit.py /tmp/acceptance.log /tmp/acceptance.junit.xml

- name: Convert unit test output to JUnit
if: always()
run: |
Expand All @@ -49,6 +59,15 @@ jobs:
reporter: java-junit
fail-on-error: false

- name: Publish acceptance report
if: always()
uses: dorny/test-reporter@v1
with:
name: Acceptance Smoke Tests
path: /tmp/acceptance.junit.xml
reporter: java-junit
fail-on-error: false

- name: Job summary
if: always()
run: |
Expand All @@ -57,4 +76,7 @@ jobs:
echo "";
echo "### Unit tests executed";
grep -E '^◇ Test ' /tmp/swift-test.log | sed -E 's/^◇ Test (.*) started\.$/- \1/' || true;
echo "";
echo "### Acceptance checks";
grep -E '^\[acceptance\] ok:' /tmp/acceptance.log | sed -E 's/^\[acceptance\] ok: /- ✅ /' || true;
} >> "$GITHUB_STEP_SUMMARY"
22 changes: 22 additions & 0 deletions .github/workflows/pr-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ jobs:
set -o pipefail
swift test 2>&1 | tee /tmp/swift-test.log

- name: Run acceptance smoke tests (capture log)
run: |
set -o pipefail
./scripts/acceptance-tests.sh 2>&1 | tee /tmp/acceptance.log

- name: Convert acceptance output to JUnit
if: always()
run: |
./scripts/acceptance-to-junit.py /tmp/acceptance.log /tmp/acceptance.junit.xml

- name: Convert unit test output to JUnit
if: always()
run: |
Expand All @@ -51,6 +61,15 @@ jobs:
reporter: java-junit
fail-on-error: false

- name: Publish acceptance report
if: always()
uses: dorny/test-reporter@v1
with:
name: Acceptance Smoke Tests
path: /tmp/acceptance.junit.xml
reporter: java-junit
fail-on-error: false

- name: Job summary
if: always()
run: |
Expand All @@ -59,4 +78,7 @@ jobs:
echo "";
echo "### Unit tests executed";
grep -E '^◇ Test ' /tmp/swift-test.log | sed -E 's/^◇ Test (.*) started\.$/- \1/' || true;
echo "";
echo "### Acceptance checks";
grep -E '^\[acceptance\] ok:' /tmp/acceptance.log | sed -E 's/^\[acceptance\] ok: /- ✅ /' || true;
} >> "$GITHUB_STEP_SUMMARY"
3 changes: 2 additions & 1 deletion Sources/gitw/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ do {
} catch let e as GitwError {
switch e {
case .usage(let msg):
die(msg, code: 0)
// Usage here indicates an error in invocation; fail closed.
die(msg, code: 2)
default:
die("gitw: \(e)")
}
Expand Down
51 changes: 51 additions & 0 deletions scripts/acceptance-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"

swift build

BIN="$ROOT_DIR/.build/debug/gitw"
if [[ ! -x "$BIN" ]]; then
echo "error: gitw binary not found at: $BIN" >&2
exit 1
fi

echo "[acceptance] gitw binary: $BIN"

# 1) Missing --as should fail closed
set +e
OUT="$($BIN whoami 2>&1)"
CODE=$?
set -e
if [[ $CODE -eq 0 ]]; then
echo "[acceptance] expected whoami without --as to fail, got exit 0" >&2
echo "$OUT" >&2
exit 1
fi
if ! echo "$OUT" | grep -qi "Missing --as"; then
echo "[acceptance] expected 'Missing --as' message" >&2
echo "$OUT" >&2
exit 1
fi

echo "[acceptance] ok: missing --as fails"

# 2) Missing --as for git invocation should fail closed
set +e
OUT="$($BIN status 2>&1)"
CODE=$?
set -e
if [[ $CODE -eq 0 ]]; then
echo "[acceptance] expected git invocation without --as to fail, got exit 0" >&2
echo "$OUT" >&2
exit 1
fi
if ! echo "$OUT" | grep -qi "Missing --as"; then
echo "[acceptance] expected 'Missing --as' message (git invocation)" >&2
echo "$OUT" >&2
exit 1
fi

echo "[acceptance] ok: git invocation missing --as fails"
53 changes: 53 additions & 0 deletions scripts/acceptance-to-junit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""Convert acceptance smoke test output to a minimal JUnit XML.

We parse lines like:
[acceptance] ok: <name>

Usage:
scripts/acceptance-to-junit.py <input_log> <output_xml>
"""

from __future__ import annotations

import sys
import time
import xml.etree.ElementTree as ET


def main() -> int:
if len(sys.argv) != 3:
print("usage: acceptance-to-junit.py <input_log> <output_xml>", file=sys.stderr)
return 2

inp, outp = sys.argv[1], sys.argv[2]

checks: list[str] = []
with open(inp, "r", encoding="utf-8", errors="replace") as f:
for line in f:
line = line.strip("\n")
if line.startswith("[acceptance] ok:"):
checks.append(line.split("[acceptance] ok:", 1)[1].strip())

suite = ET.Element("testsuite")
suite.set("name", "acceptance")
suite.set("timestamp", time.strftime("%Y-%m-%dT%H:%M:%S"))
suite.set("tests", str(len(checks)))
suite.set("failures", "0")

for name in checks:
tc = ET.SubElement(suite, "testcase")
tc.set("name", name)
tc.set("classname", "gitw")
tc.set("time", "0")

tree = ET.ElementTree(suite)
ET.indent(tree, space=" ")
with open(outp, "wb") as f:
tree.write(f, encoding="utf-8", xml_declaration=True)

return 0


if __name__ == "__main__":
raise SystemExit(main())
Loading