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
28 changes: 28 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Summary

<!-- What changed and why -->

## Type

- [ ] Feature
- [ ] Bug fix
- [ ] Docs / README
- [ ] Chore / CI
- [ ] Release

## Checklist

- [ ] Branched from `develop` (not committing directly to `develop`)
- [ ] `Scripts/run_pr_checks.sh` passes locally (or `run_governance_checks.sh` + `run_macos_checks.sh` on macOS)
- [ ] New or changed public APIs have DocC entries and token/tests/showcase coverage where applicable
- [ ] README/showcase images updated when UI changed (`Scripts/capture_showcase_snapshots.sh`, manual — not run in CI)
- [ ] UI changes include HIG checklist notes (if applicable)
- [ ] `Docs/PRD.md` / `Requirements/*/REQ.md` updated (if public API or behavior changed)

## Test plan

<!-- Commands run, platforms checked, screenshots if UI -->

## Screenshots

<!-- Showcase snapshots, Xcode previews, or simulator captures for UI changes -->
31 changes: 0 additions & 31 deletions .github/workflows/build-and-test.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/deploy-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Deploy GitHub Pages

on:
push:
branches: [main, develop]
branches: [develop]
paths:
- pages/**
- .github/workflows/deploy-pages.yml
Expand Down
23 changes: 22 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,22 @@ HIGFoundations
* Platform differences belong in `HIGPlatform` or component-specific adapters, not scattered `#if os()` blocks.
* Keep PRs small and module-focused.

Git Workflow (required)

* **Never push directly to `develop` or `main`.** All changes land through pull requests.
* Branch from `develop`: `feature/…`, `fix/…`, `chore/…`, or `docs/…`.
* Push your branch and open a PR targeting `develop`.
* Wait for CI (`Build and Test`) to pass before merge.
* Squash-merge or merge via GitHub UI after review. Do not fast-forward push to `develop` from a local checkout.
* Release tags (`v*`) are cut from `develop` only after the release PR is merged.

Swift Concurrency Rules

* Use Swift 6 strict concurrency.
* Prefer `Sendable` token structs and protocol requirements where practical.
* Mark UI-facing theme and environment types with `@MainActor` when they touch SwiftUI state.
* Use `async`/`await` only where side effects exist; token and component rendering should stay synchronous unless bridging requires otherwise.
* Avoid GCD and `DispatchQueue` unless an Apple API explicitly requires it.
* Do not use GCD or `DispatchQueue`; use Swift concurrency (`Task`, `async`/`await`, actors) instead. Run `Scripts/verify_no_gcd.sh`.

HIGFoundations Rules

Expand Down Expand Up @@ -242,6 +251,18 @@ Development Environment Rules

Verification Commands

Local verification (run before opening a PR):

Scripts/build_all_platforms.sh

swift test

Scripts/verify_sample_xcode_project.sh

Showcase snapshot capture (`Scripts/capture_showcase_snapshots.sh`) is manual for README/Pages images only.

Individual guards (debugging):

Requirements guard:

Scripts/verify_requirements_present.sh
Expand Down
9 changes: 8 additions & 1 deletion CODING_STANDARDS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
CODING STANDARDS - HIGDesign Project

Git Workflow

* Never commit or push directly to `develop` or `main`.
* Create a topic branch from `develop`, push the branch, and open a pull request.
* Keep PRs focused (one feature or fix per PR when practical).
* Ensure CI passes before requesting merge.

Architecture

* HIGDesign must use a layered Swift Package Manager module graph.
Expand Down Expand Up @@ -96,7 +103,7 @@ Swift Concurrency Rules
* Prefer `Sendable` token structs and enums.
* Mark UI-facing theme APIs with `@MainActor` when needed.
* UI updates must be main-actor safe.
* Avoid GCD and `DispatchQueue` unless an Apple API explicitly requires it.
* Do not use GCD or `DispatchQueue`; use Swift concurrency (`Task`, `async`/`await`, actors) instead. Enforced by `Scripts/verify_no_gcd.sh`.

File Organization

Expand Down
6 changes: 6 additions & 0 deletions Docs/AGENT_RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ These rules apply to automated and human-assisted coding agents working in this
- The library supports iOS, iPadOS, macOS, visionOS, tvOS, and watchOS.
- HIGDesign is not an application. Do not add app-only concerns such as persistence, sync, purchases, or moderation unless explicitly requested.

## Git workflow

- Never push directly to `develop` or `main`.
- Branch from `develop`, push the branch, and open a pull request.
- Wait for the `Build and Test` workflow to pass before merge.

## Architecture

- Use modular Swift Package Manager targets with an acyclic dependency graph.
Expand Down
25 changes: 7 additions & 18 deletions Docs/DEVELOPMENT_ENVIRONMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,16 @@ Minimum deployment targets cover the latest three calendar years:
Run from repository root:

```bash
Scripts/verify_requirements_present.sh
Scripts/verify_ui_guidelines_present.sh
Scripts/verify_xcode_previews_present.sh
Scripts/verify_view_naming.sh
Scripts/verify_component_token_usage.sh
Scripts/verify_photo_picker_token_usage.sh
Scripts/verify_no_uikit.sh
Scripts/verify_showcase_coverage.sh
Scripts/verify_docc_coverage.sh
Scripts/verify_showcase_snapshots_present.sh
Scripts/verify_showcase_snapshot_diff.sh
Scripts/build_all_platforms.sh
swift test
Scripts/verify_sample_xcode_project.sh
Scripts/publish_showcase_snapshots.sh

Showcase snapshot capture is manual — for README and GitHub Pages images only:

Scripts/capture_showcase_snapshots.sh
```

```bash
swift build --package-path .
swift test --package-path .
Scripts/build_all_platforms.sh
```
Individual guards remain available under `Scripts/verify_*.sh` when debugging a single failure.

## Agent Workflow

Expand All @@ -61,7 +50,7 @@ Scripts/build_all_platforms.sh

## Current Milestone

Phase 13 v1.0.0 preparation. All platform builds, tests, showcase build, coverage guards, DocC coverage, automated snapshot capture (including brand theme variants), and snapshot diff verification are mandatory before merging UI changes.
Phase 13 v1.0.0 preparation. Run builds, tests, and individual `Scripts/verify_*.sh` guards locally before opening a PR. Regenerate showcase PNGs manually when updating README or Pages imagery.

## Xcode

Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ A **Swift Package** with HIG-correct SwiftUI components, design tokens, and them
| Spacing and colors drift across screens | Token layers enforce consistency |
| Brand theming means touching every view | Swap theme at the root — everything updates |
| Multi-platform means re-solving the same patterns | Platform-appropriate behavior built in |
| No visual regression baseline | 385 committed showcase snapshots in CI |
| Marketing gallery | 385 showcase snapshots for README and GitHub Pages |

Native SwiftUI is the foundation. HIGDesign is the **opinionated layer** that saves weeks of design-system work while keeping you aligned with [Apple Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/).

Expand Down Expand Up @@ -122,7 +122,7 @@ Themes: **System** · **High Contrast** · **Brand accent** — each with light
- **Environment-driven theming** — `@Environment(\.higTheme)` everywhere
- **Modular SPM products** — `HIGDesign` umbrella or `HIGDesignCore` + `HIGDesignComponents`
- **DocC catalog** — open in Xcode → *Product → Build Documentation*
- **CI-verified** — token guards, snapshot diff, 45 unit tests, six-platform builds
- **CI-verified** — token guards, 47 unit tests, six-platform builds

## Documentation

Expand All @@ -133,15 +133,16 @@ Themes: **System** · **High Contrast** · **Brand accent** — each with light
| [Swift Package Index](https://swiftpackageindex.com/S-M-Technology-Ltd/HIGDesign) | Builds & API browser |
| [CHANGELOG.md](CHANGELOG.md) | Release notes |
| [ARCHITECTURE.md](Docs/ARCHITECTURE.md) | Module graph (for contributors) |
| [Requirements](Requirements/README.md) | Per-module requirements |

## Contributing

PRs welcome. Run before submitting:

```bash
swift build && swift test
Scripts/verify_component_token_usage.sh
Scripts/verify_showcase_snapshot_diff.sh
Scripts/build_all_platforms.sh
swift test
Scripts/verify_sample_xcode_project.sh
```

## License
Expand Down
2 changes: 1 addition & 1 deletion Scripts/publish_showcase_snapshots.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mkdir -p "$SNAPSHOT_DIR" "$PLATFORM_DIR"/{macos,ios,ipados,visionos,tvos,watchos
components=()
while IFS= read -r component; do
components+=("$component")
done < <(rg -o 'case ([a-zA-Z]+)' Showcase/ShowcaseComponent.swift | sed -E 's/case //' | sort -u)
done < <(grep -oE 'case ([a-zA-Z]+)' Showcase/ShowcaseComponent.swift | sed -E 's/case //' | sort -u)

if ((${#components[@]} == 0)); then
echo "No ShowcaseComponent cases found." >&2
Expand Down
2 changes: 1 addition & 1 deletion Scripts/verify_docc_coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ EXPECTED_SYMBOLS=(

missing=()
for symbol in "${EXPECTED_SYMBOLS[@]}"; do
if ! rg -q "${symbol}" "$DOCC_DIR"; then
if ! grep -rq "${symbol}" "$DOCC_DIR"; then
missing+=("$symbol")
fi
done
Expand Down
3 changes: 2 additions & 1 deletion Scripts/verify_no_committed_signing.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"

if rg -n 'DEVELOPMENT_TEAM|PROVISIONING_PROFILE' Sample/HIGDesignSample.xcodeproj/project.pbxproj 2>/dev/null; then
if grep -nE 'DEVELOPMENT_TEAM|PROVISIONING_PROFILE' Sample/HIGDesignSample.xcodeproj/project.pbxproj >/dev/null 2>&1; then
grep -nE 'DEVELOPMENT_TEAM|PROVISIONING_PROFILE' Sample/HIGDesignSample.xcodeproj/project.pbxproj >&2
echo "Committed signing guard failed: keep team/profile overrides in Sample/Config/Signing.local.xcconfig only." >&2
exit 1
fi
Expand Down
15 changes: 15 additions & 0 deletions Scripts/verify_no_gcd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"

PATTERN='DispatchQueue|dispatch_async|dispatch_sync|dispatch_get_main_queue|DispatchGroup|DispatchSemaphore|DispatchWorkItem|DispatchSource|DispatchSpecificKey|DispatchTime'

if grep -rEn "$PATTERN" Sources Tests >/dev/null 2>&1; then
grep -rEn "$PATTERN" Sources Tests >&2
echo "GCD guard failed: use Swift concurrency (Task, async/await, actors) instead of GCD." >&2
exit 1
fi

echo "GCD guard passed: no DispatchQueue or dispatch_* APIs in Sources or Tests."
3 changes: 2 additions & 1 deletion Scripts/verify_no_uikit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ cd "$ROOT"

PATTERN='import UIKit|import UIKit\.|UIColor\.|UIAccessibility\.|UIViewRepresentable|UIViewControllerRepresentable'

if rg -n "$PATTERN" Sources Tests; then
if grep -rEn "$PATTERN" Sources Tests >/dev/null 2>&1; then
grep -rEn "$PATTERN" Sources Tests >&2
echo "UIKit guard failed: HIGDesign sources must use SwiftUI only." >&2
exit 1
fi
Expand Down
6 changes: 3 additions & 3 deletions Scripts/verify_photo_picker_token_usage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ if [[ ! -d "$PHOTO_PICKER_DIR" ]]; then
exit 1
fi

if rg -n 'PickerDesign' "$PHOTO_PICKER_DIR" >/dev/null 2>&1; then
if grep -rn 'PickerDesign' "$PHOTO_PICKER_DIR" >/dev/null 2>&1; then
echo "Photo picker token guard failed: PickerDesign is deprecated; use theme.photoPicker tokens." >&2
rg -n 'PickerDesign' "$PHOTO_PICKER_DIR" >&2 || true
grep -rn 'PickerDesign' "$PHOTO_PICKER_DIR" >&2 || true
exit 1
fi

Expand All @@ -28,7 +28,7 @@ PATTERNS=(
)

for pattern in "${PATTERNS[@]}"; do
if matches="$(rg -n "$pattern" "${VIEW_FILES[@]}" 2>/dev/null || true)"; then
if matches="$(grep -En "$pattern" "${VIEW_FILES[@]}" 2>/dev/null || true)"; then
if [[ -n "$matches" ]]; then
echo "Photo picker token guard failed: hardcoded visual value matching '$pattern'." >&2
echo "$matches" >&2
Expand Down
6 changes: 3 additions & 3 deletions Scripts/verify_requirements_present.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ for module in "${required_modules[@]}"; do
continue
fi

if ! rg -q '^## (All platforms|Requirements)' "$req_file"; then
if ! grep -Eq '^## (All platforms|Requirements)' "$req_file"; then
missing+=("Requirements/$module/REQ.md (missing requirements section)")
fi

if ! rg -q '^### (iOS|macOS|watchOS|tvOS|visionOS)' "$req_file"; then
if ! grep -Eq '^### (iOS|macOS|watchOS|tvOS|visionOS)' "$req_file"; then
missing+=("Requirements/$module/REQ.md (missing platform section)")
fi
done

readme_doc="$ROOT_DIR/README.md"
if ! rg -q 'Requirements/' "$readme_doc"; then
if ! grep -q 'Requirements/' "$readme_doc"; then
echo "README.md must link Requirements/" >&2
exit 1
fi
Expand Down
4 changes: 2 additions & 2 deletions Scripts/verify_sample_xcode_project.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ fi

PROJECT="$ROOT/Sample/HIGDesignSample.xcodeproj"

if ! rg -q 'INFOPLIST_KEY_NSPhotoLibraryUsageDescription' "$PROJECT/project.pbxproj"; then
if ! grep -q 'INFOPLIST_KEY_NSPhotoLibraryUsageDescription' "$PROJECT/project.pbxproj"; then
echo "Sample Xcode project guard failed: iOS target is missing NSPhotoLibraryUsageDescription." >&2
exit 1
fi

if ! rg -q 'INFOPLIST_KEY_PHPhotoLibraryPreventAutomaticLimitedAccessAlert' "$PROJECT/project.pbxproj"; then
if ! grep -q 'INFOPLIST_KEY_PHPhotoLibraryPreventAutomaticLimitedAccessAlert' "$PROJECT/project.pbxproj"; then
echo "Sample Xcode project guard failed: iOS target is missing PHPhotoLibraryPreventAutomaticLimitedAccessAlert." >&2
exit 1
fi
Expand Down
10 changes: 7 additions & 3 deletions Scripts/verify_showcase_coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ EXPECTED=(

missing=()
for component in "${EXPECTED[@]}"; do
if ! rg -q "case ${component}" Showcase/ShowcaseComponent.swift; then
if ! grep -q "case ${component}" Showcase/ShowcaseComponent.swift; then
missing+=("$component")
fi
done
Expand Down Expand Up @@ -75,10 +75,14 @@ while IFS= read -r component; do
echo "Showcase coverage guard failed: no mapping for ${component}." >&2
exit 1
fi
if ! rg -q "case ${showcase_key}" Showcase/ShowcaseComponent.swift; then
if ! grep -q "case ${showcase_key}" Showcase/ShowcaseComponent.swift; then
echo "Showcase coverage guard failed: ${component} has no ShowcaseComponent case (${showcase_key})." >&2
exit 1
fi
done < <(rg --no-filename -o 'public struct (HIG[A-Za-z]+).*: View( \{| where)' Sources/HIGComponents | sed -E 's/public struct (HIG[A-Za-z]+).*/\1/' | sort -u)
done < <(
grep -rhoE 'public struct (HIG[A-Za-z]+).*: View( \{| where)' Sources/HIGComponents 2>/dev/null \
| sed -E 's/public struct (HIG[A-Za-z]+).*/\1/' \
| sort -u
)

echo "Showcase coverage guard passed: all public components are represented in Showcase."
Loading