diff --git a/.doccTargetList b/.doccTargetList new file mode 100644 index 0000000..4bc365c --- /dev/null +++ b/.doccTargetList @@ -0,0 +1 @@ +Add one target per line \ No newline at end of file diff --git a/.github/workflows/docc_deploy.yml b/.github/workflows/docc_deploy.yml new file mode 100644 index 0000000..b5eec08 --- /dev/null +++ b/.github/workflows/docc_deploy.yml @@ -0,0 +1,65 @@ +name: DocC Deploy + +on: + workflow_call: + inputs: + docc_swift_version: + type: string + description: "Swift version used to generate DocC documentation." + default: "6.2" + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-docc + cancel-in-progress: true + + +jobs: + + generate-docc: + name: Generate DocC documentation + runs-on: ubuntu-latest + + container: + image: swift:${{ inputs.docc_swift_version }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install curl + jq + run: | + apt-get update -y + apt-get install -y curl jq + + - name: Generate DocC documentation + run: | + curl -s https://raw.githubusercontent.com/BinaryBirds/github-workflows/refs/heads/feature/docc/scripts/generate-docc.sh | bash -s -- --name ${{ github.event.repository.name }} + + - name: Upload DocC artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs + + + deploy: + name: Deploy DocC to GitHub Pages + needs: generate-docc + runs-on: ubuntu-latest + + permissions: + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deploy.outputs.page_url }} + + steps: + - name: Deploy to GitHub Pages + id: deploy + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.github/workflows/extra_soundness.yml b/.github/workflows/extra_soundness.yml index 0485bfb..598fcd4 100644 --- a/.github/workflows/extra_soundness.yml +++ b/.github/workflows/extra_soundness.yml @@ -7,6 +7,10 @@ on: type: boolean description: "Boolean to enable the local swift dependencies check job. Defaults to false." default: false + headers_check_enabled: + type: boolean + description: "Checks Swift source file headers to ensure they follow the correct format. Defaults to false." + default: false run_tests_with_cache_enabled: type: boolean description: "Boolean to enable run tests with .build cache." @@ -14,7 +18,7 @@ on: run_tests_swift_versions: type: string description: "List of Swift versions to test with." - default: '["6.0", "6.1"]' + default: '["6.1", "6.2"]' secrets: SSH_PRIVATE_KEY: required: false @@ -35,7 +39,22 @@ jobs: with: persist-credentials: false - name: Run local swift dependencies check - run: curl -s https://raw.githubusercontent.com/BinaryBirds/github-workflows/refs/heads/main/scripts/check-local-swift-dependencies.sh | bash + run: curl -s https://raw.githubusercontent.com/BinaryBirds/github-workflows/refs/heads/feature/docc/scripts/check-local-swift-dependencies.sh | bash + + + swift_headers_check: + name: Checks Swift source file headers + if: ${{ inputs.headers_check_enabled }} + runs-on: ubuntu-latest + timeout-minutes: 1 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Run swift headers check + run: curl -s https://raw.githubusercontent.com/BinaryBirds/github-workflows/refs/heads/feature/docc/scripts/check-swift-headers.sh | bash + cache-and-test: name: Run tests with cache diff --git a/LICENSE b/LICENSE index 45f679e..2bf8293 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -MIT License +# MIT License -Copyright (c) 2024 Binary Birds Ltd. +Copyright (c) 2025 Binary Birds Ltd. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/Makefile b/Makefile index 9e62eab..ca40c17 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,20 @@ breakage: symlinks: curl -s $(baseUrl)/check-broken-symlinks.sh | bash +## params: --local: generate for local testing +docc-generate: + curl -s $(baseUrl)/generate-docc.sh | bash + +docc-local: + curl -s $(baseUrl)/generate-docc.sh | bash -s -- --local + docc-warnings: curl -s $(baseUrl)/check-docc-warnings.sh | bash +## params: -n: name, -p: port +run-docc: + curl -s $(baseUrl)/run-docc-docker.sh | bash + headers: curl -s $(baseUrl)/check-swift-headers.sh | bash @@ -52,4 +63,4 @@ lint: format: curl -s $(baseUrl)/run-swift-format.sh | bash -s -- --fix -check: symlinks language deps lint \ No newline at end of file +check: symlinks language deps lint docc-warnings headers diff --git a/README.md b/README.md index 2e18047..6283eee 100644 --- a/README.md +++ b/README.md @@ -1,111 +1,411 @@ # GitHub Actions Workflows + This repository contains a reusable workflow and various bash scripts designed to streamline tasks in a Swift project. The workflow utilizes the official [swiftlang/github-workflows](https://github.com/swiftlang/github-workflows) to perform checks and run Swift tests on the repository. ## Install + No installation required. -## How to use the workflow? -To use the workflow in a repository, simply copy the **sample_actions.yml** file into the **.github/workflows** directory within the repository. For more configuration options, refer to the official [swiftlang/github-workflows](https://github.com/swiftlang/github-workflows) repository. +## Workflows + +This section details the reusable workflows provided by the repository. + +### 1. Extra Soundness Workflow (`extra_soundness.yml`) + +This workflow provides configurable, robust checks and testing: + +* **Optional Local Swift Dependency Checks**: Checks for accidental `.package(path:)` usage. +* **Optional Swift Test Execution**: Runs tests using **`.build` caching** for efficiency. +* **Multi-Version Support**: Tests across multiple Swift versions, configurable via input (defaulting to `["6.0", "6.1"]`). +* **SSH Support**: Includes steps to set up **SSH credentials** (via the `SSH_PRIVATE_KEY` secret) for projects relying on private Git dependencies. + +**Example Usage (Caller Repository):** + +```yaml +jobs: + soundness: + uses: BinaryBirds/github-workflows/.github/workflows/extra_soundness.yml@main + with: + local_swift_dependencies_check_enabled: true + run_tests_with_cache_enabled: true + run_tests_swift_versions: '["6.0","6.1"]' +``` + +### 2. DocC Deploy Workflow (`docc_deploy.yml`) + +This workflow handles the generation and deployment of DocC documentation: + +* **Builds DocC Documentation**: Uses a Swift Docker image (default version "6.2") to build the documentation. +* **Deploys to GitHub Pages**: Uses `actions/deploy-pages@v4` to publish the results. +* **Note on Stability**: This workflow is currently configured to fetch its core script (`generate-docc.sh`) from the **`feature/docc`** branch. + +**Example Usage (Caller Repository):** + +```yaml +jobs: + create-docc-and-deploy: + uses: BinaryBirds/github-workflows/.github/workflows/docc_deploy.yml@main + permissions: + contents: read + pages: write + id-token: write + with: + docc_swift_version: "6.1" +``` + +----- + +## Makefile Usage + +A **Makefile** is included to simplify the execution of all automation tasks by converting long `curl | bash` commands into short, memorable `make` targets. -## How to use the script(s)? -A **Makefile** is included in this repository to simplify script execution. Copy it to the repository’s root directory where the scripts will be used. +### Combined Makefile Commands -## Available scripts +The `check` target is a composite command that executes several core quality checks sequentially. + +* `check`: Executes `make symlinks` -\> `make language` -\> `make deps` -\> `make lint`. + +### Benefits + +* **Standardizes script usage** and ensures consistent options. +* **Shortens long commands** into memorable tasks. +* Supports composite commands and reduces human error. + +----- + +## Available Scripts Documentation + +The `Makefile` uses the variable `baseUrl` which points to the source of all scripts: +`https://raw.githubusercontent.com/BinaryBirds/github-workflows/refs/heads/main/scripts` ### check-api-breakage.sh -This script runs a check for any breaking changes in the API. It uses the swift package diagnose-api-breaking-changes command to analyze the current API against the last tagged version and reports any breaking changes found. -Usage: `make breakage` +**Purpose**: Detects API-breaking changes compared to the latest Git tag using the `swift package diagnose-api-breaking-changes` command. + +**Makefile Command**: + +```sh +make breakage +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/check-api-breakage.sh | bash +``` + +----- ### check-broken-symlinks.sh -This script runs a search to find and report broken symbolic links within the repository. It iterates over all files tracked by Git and checks if their symlink targets exist. -Usage: `make symlinks` +**Purpose**: Runs a search to find and report **broken symbolic links** within the repository. + +**Makefile Command**: + +```sh +make symlinks +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/check-broken-symlinks.sh | bash +``` + +----- ### check-docc-warnings.sh -This script executes Swift Package Manager’s documentation generation with the **--warnings-as-errors** flag to ensure that any documentation warnings are treated as errors, maintaining high-quality documentation standards. -Usage: `make docc-warnings` +**Purpose**: Executes DocC documentation analysis with the **`--warnings-as-errors`** flag to enforce strict quality standards. -### check-swift-headers.sh -This script checks and optionally fixes Swift source file headers to ensure they follow a consistent format. -Optional parameters can used, these extra parameters needs to be added in the **Makefile**: -- `--fix`: Automatically fix all headers -- `--author`: Set a custom author name (default is `"Binary Birds"`) - -Fix all headers: -`fix-headers: - curl -s $(baseUrl)/check-swift-headers.sh | bash -s -- --fix -` -Fix all headers with custom author: -`fix-headers: - curl -s $(baseUrl)/run-openapi-docker.sh | bash -s -- --fix --author John -` -Usage: `make headers` +**Makefile Command**: + +```sh +make docc-warnings +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/check-docc-warnings.sh | bash +``` + +----- ### check-local-swift-dependencies.sh -This script checks for local Swift package dependencies in the repository. It scans **Package.swift** files for local dependencies defined using **.package(path:)** and reports any occurrences. -Usage: `make deps` - +**Purpose**: Checks for accidental local Swift package dependencies by scanning for **`.package(path:)`** usage in `Package.swift` files. + +**Makefile Command**: + +```sh +make deps +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/check-local-swift-dependencies.sh | bash +``` + +----- + ### check-openapi-security.sh -This script runs a security analysis on the OpenAPI specification using OWASP ZAP. It runs the zap-api-scan.py script inside a Docker container to check for security vulnerabilities in the OpenAPI definition. -Usage: `make openapi-security` +**Purpose**: Runs a **security analysis** on the OpenAPI specification using **OWASP ZAP** inside a Docker container. + +**Makefile Command**: + +```sh +make openapi-security +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/check-openapi-security.sh | bash +``` + +----- ### check-openapi-validation.sh -This script validates the OpenAPI specification for compliance with the OpenAPI standard. It uses the openapi-spec-validator tool inside a Docker container to perform the validation. -Usage: `make openapi-validation` +**Purpose**: Validates the `openapi.yaml` file for compliance with the OpenAPI standard using the `openapi-spec-validator` tool in a Docker container. + +**Makefile Command**: + +```sh +make openapi-validation +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/check-openapi-validation.sh | bash +``` + +----- + +### check-swift-headers.sh + +**Purpose**: Checks and optionally fixes Swift source file headers to ensure they follow a consistent 5-line format. +**Configuration**: Respects the **`.swiftheaderignore`** file, which lists file paths, directories, or glob patterns to exclude from header validation. + +**Parameters**: + +* `--fix`: Automatically inserts or updates headers in-place. +* `--author `: Overrides the default author name (`"Binary Birds"`). + +**Makefile Command (Check)**: + +```sh +make headers +``` + +**Raw curl Command (Check)**: + +```sh +curl -s $(baseUrl)/check-swift-headers.sh | bash +``` + +**Makefile Command (Fix)**: + +```sh +make fix-headers +``` + +**Raw curl Command (Fix with Author Example)**: + +```sh +curl -s $(baseUrl)/check-swift-headers.sh | bash -s -- --fix --author "John Doe" +``` + +----- ### check-unacceptable-language.sh -This script searches the codebase for unacceptable language patterns. It uses a predefined list of terms and searches the codebase for any matches, reporting them if found. An optional **.unacceptablelanguageignore** file can be added to the repository’s root, allowing certain files to be ignored during the search. -Usage: `make language` +**Purpose**: Searches the codebase for unacceptable language patterns (e.g., `master`, `blacklist`). +**Configuration**: Respects the **`.unacceptablelanguageignore`** file, which allows you to ignore specific files or directories when scanning for unacceptable language. + +**Makefile Command**: + +```sh +make language +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/check-unacceptable-language.sh | bash +``` + +----- ### generate-contributors-list.sh -This script generates a list of contributors for the repository. It uses the git shortlog command to gather commit information and formats it into a CONTRIBUTORS.txt file. -Usage: `make contributors` +**Purpose**: Generates a list of contributors for the repository into a **`CONTRIBUTORS.txt`** file from Git commit history. + +**Makefile Command**: + +```sh +make contributors +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/generate-contributors-list.sh | bash +``` + +----- + +### generate-docc.sh + +**Purpose**: Generates DocC documentation to the `docs/` directory. +**Configuration**: Looks for the **`.doccTargetList`** file, which, if present, explicitly defines the Swift targets for documentation generation. + +**Parameters**: + +* `--local`: Enables local mode (no hosting transforms). +* `--name `: Sets the hosting base path for GitHub Pages. + +**Makefile Command**: + +```sh +make docc-generate +``` + +**Raw curl Command (GitHub Pages Example)**: + +```sh +curl -s $(baseUrl)/generate-docc.sh | bash -s -- --name MyRepoName +``` + +----- + +### install-swift-format.sh + +**Purpose**: Installs the **Swift Format** tool binary. + +**Makefile Command**: + +```sh +make install-format +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/install-swift-format.sh | bash +``` + +----- ### install-swift-openapi-generator.sh -This script installs the Swift OpenAPI generator tool, the version can be optionally defined using the `-v` parameter. If no version is specified as a parameter, the latest version will be installed. -Example to add the extra parameter in the **Makefile**: -`install-openapi: - curl -s $(baseUrl)/install-swift-openapi-generator.sh | bash -s -- -v 1.2.2 -` +**Purpose**: Installs the **Swift OpenAPI Generator** tool. + +**Parameters**: + +* `-v `: Specifies the version to install. + +**Makefile Command**: + +```sh +make install-openapi +``` + +**Raw curl Command (Version Example)**: + +```sh +curl -s $(baseUrl)/install-swift-openapi-generator.sh | bash -s -- -v 1.2.2 +``` + +----- -Usage: `make install-openapi` - ### run-clean.sh -This script cleans up build artifacts and other temporary files from the repository. -Usage: `make run-clean` +**Purpose**: Cleans up build artifacts and other temporary files (e.g., `.build`, `.swiftpm`). + +**Makefile Command**: + +```sh +make run-clean +``` + +**Raw curl Command**: + +```sh +curl -s $(baseUrl)/run-clean.sh | bash +``` + +----- + +### run-docc-docker.sh + +**Purpose**: Serves the generated DocC documentation using a Docker container running Nginx. + +**Parameters**: + +* `-n `: Adds a custom identifier for the container. +* `-p `: Adds a custom port mapping (default: `8000:80`). + +**Makefile Command**: + +```sh +make run-docc +``` + +**Raw curl Command (Custom Port Example)**: + +```sh +curl -s $(baseUrl)/run-docc-docker.sh | bash -s -- -p 8800:80 +``` + +----- ### run-openapi-docker.sh -This script serves the OpenAPI documentation using an Nginx server. This try to run inside a Docker container. Optional parameters can used, these extra parameters needs to be added in the **Makefile**: -- `-n` : add a custom identifier for the container, the default is `openapi-server` -- `-p` : add a custom port to bind it to the container, the default is `8888:80` +**Purpose**: Serves the OpenAPI documentation using a Docker container running Nginx. + +**Parameters**: + +* `-n `: Adds a custom identifier for the container. +* `-p `: Adds a custom port mapping (default: `8888:80`). +**Makefile Command**: -Example to add a different name: -`run-openapi: - curl -s $(baseUrl)/run-openapi-docker.sh | bash -s -- -n new-name -` +```sh +make run-openapi +``` -Example to add a different port: -`run-openapi: - curl -s $(baseUrl)/run-openapi-docker.sh | bash -s -- -p 8800:80 -` +**Raw curl Command (Custom Name Example)**: -Usage: `make run-openapi` +```sh +curl -s $(baseUrl)/run-openapi-docker.sh | bash -s -- -n new-name +``` + +----- ### run-swift-format.sh -This script checks/formats Swift code using the swift-format tool. It runs the tool on all Swift files in the repository, optionally fixing issues if the --fix argument is provided. -The script attempts to read the **.swift-format** configuration file for format rules and ignores files listed in **.swiftformatignore**, if present. If any file is missing, it will download it to the repository, which can then be customized. -Usage: `make lint` for run lint or `make format` for run format +**Purpose**: Checks/formats Swift code using the `swift-format` tool. If configuration is missing, it downloads defaults. +**Configuration**: Uses the **`.swift-format`** file for format rules and the **`.swiftformatignore`** file to exclude files/directories from the process. + +**Parameters**: + +* `--fix`: Automatically applies formatting instead of checking. + +**Makefile Command (Check)**: + +```sh +make lint +``` + +**Raw curl Command (Fix)**: + +```sh +curl -s $(baseUrl)/run-swift-format.sh | bash -s -- --fix +``` diff --git a/sample_actions.yml b/sample_actions.yml index 778390b..df114bc 100644 --- a/sample_actions.yml +++ b/sample_actions.yml @@ -15,8 +15,8 @@ jobs: format_check_enabled : true broken_symlink_check_enabled : true unacceptable_language_check_enabled : true + docs_check_enabled : true api_breakage_check_enabled : false - docs_check_enabled : false license_header_check_enabled : false shell_check_enabled : false yamllint_check_enabled : false @@ -27,4 +27,6 @@ jobs: uses: BinaryBirds/github-workflows/.github/workflows/extra_soundness.yml@main with: local_swift_dependencies_check_enabled : true - run_tests_with_cache_enabled : true \ No newline at end of file + run_tests_with_cache_enabled : true + headers_check_enabled : true + run_tests_swift_versions: '["6.1","6.2"]' diff --git a/sample_tag_action.yml b/sample_tag_action.yml new file mode 100644 index 0000000..9dbdd18 --- /dev/null +++ b/sample_tag_action.yml @@ -0,0 +1,18 @@ +name: Create DocC and Deploy it + +on: + push: + tags: + - 'v*' + - '[0-9]*' + +jobs: + + create-docc-and-deploy: + uses: BinaryBirds/github-workflows/.github/workflows/docc_deploy.yml@main + permissions: + contents: read + pages: write + id-token: write + with: + docc_swift_version: "6.1" \ No newline at end of file diff --git a/scripts/check-docc-warnings.sh b/scripts/check-docc-warnings.sh index 2e610b1..cc0086e 100755 --- a/scripts/check-docc-warnings.sh +++ b/scripts/check-docc-warnings.sh @@ -1,25 +1,64 @@ #!/usr/bin/env bash set -euo pipefail -log() { printf -- "** %s\n" "$*" >&2; } +log() { printf -- "** %s\n" "$*" >&2; } error() { printf -- "** ERROR: %s\n" "$*" >&2; } fatal() { error "$@"; exit 1; } REPO_ROOT="$(git -C "$PWD" rev-parse --show-toplevel)" +TARGETS="" +TARGET_LIST=() -log "Checking required environment variables..." -test -n "${DOCC_TARGET:-}" || fatal "DOCC_TARGET unset" +# Auto-detect documentable Swift targets +log "Detecting Swift targets for DocC analysis…" -swift package --package-path "${REPO_ROOT}" plugin generate-documentation \ - --product "${DOCC_TARGET}" \ - --analyze \ - --level detailed \ - --warnings-as-errors \ - && DOCC_PLUGIN_RC=$? || DOCC_PLUGIN_RC=$? +if ! command -v jq >/dev/null 2>&1; then + fatal "jq is required. Install with: brew install jq" +fi + +TARGETS=$(swift package dump-package \ + | jq -r '.targets[] + | select(.type == "regular" or .type == "executable") + | .name') + +if [ -z "$TARGETS" ]; then + fatal "No documentable targets found in Package.swift" +fi + +# Convert to array +while IFS= read -r TARGET; do + TARGET_LIST+=("$TARGET") +done <<< "$TARGETS" + +TARGET_COUNT="${#TARGET_LIST[@]}" + +log "Found targets:" +printf "%s\n" "${TARGET_LIST[@]}" +log "Target count: $TARGET_COUNT" + +# Run DocC analysis (per target) +echo +TOTAL_RC=0 +for TARGET in "${TARGET_LIST[@]}"; do + set +e + swift package \ + --package-path "$REPO_ROOT" \ + plugin \ + generate-documentation \ + --target "$TARGET" \ + --analyze \ + --warnings-as-errors + RC=$? + set -e + if [ "$RC" -ne 0 ]; then + error "DocC analysis failed for target '$TARGET'" + TOTAL_RC=$RC + fi +done -if [ "${DOCC_PLUGIN_RC}" -ne 0 ]; then - fatal "❌ Generating documentation produced warnings and/or errors." - exit "${DOCC_PLUGIN_RC}" +# Final result +if [ "$TOTAL_RC" -ne 0 ]; then + fatal "Documentation analysis failed." fi -log "✅ Generated documentation with no warnings." \ No newline at end of file +log "All targets passed DocC analysis without warnings." \ No newline at end of file diff --git a/scripts/check-swift-headers.sh b/scripts/check-swift-headers.sh index eee5448..1151822 100755 --- a/scripts/check-swift-headers.sh +++ b/scripts/check-swift-headers.sh @@ -170,6 +170,9 @@ else log "No exclusion file found, using default exclusions" EXCLUDE_PATTERNS+=(":(exclude).*") EXCLUDE_PATTERNS+=(":(exclude)*.txt") + EXCLUDE_PATTERNS+=(":(exclude)*.png") + EXCLUDE_PATTERNS+=(":(exclude)*.jpeg") + EXCLUDE_PATTERNS+=(":(exclude)*.jpg") EXCLUDE_PATTERNS+=(":(exclude)*.sh") EXCLUDE_PATTERNS+=(":(exclude)*.html") EXCLUDE_PATTERNS+=(":(exclude)*.yaml") diff --git a/scripts/generate-docc.sh b/scripts/generate-docc.sh new file mode 100755 index 0000000..c1565ee --- /dev/null +++ b/scripts/generate-docc.sh @@ -0,0 +1,128 @@ +#!/usr/bin/env bash +set -euo pipefail + +log() { printf -- "** %s\n" "$*" >&2; } +error() { printf -- "** ERROR: %s\n" "$*" >&2; } +fatal() { error "$@"; exit 1; } + +OUTPUT_DIR="./docs" +TARGETS_FILE=".doccTargetList" +TARGETS="" +TARGET_FLAGS=() +COMBINED_FLAG="" +LOCAL_MODE=false +REPO_NAME="" + +# Argument parsing +while [[ $# -gt 0 ]]; do + case "$1" in + --local) + LOCAL_MODE=true + shift + ;; + --name) + if [[ -n "${2:-}" ]]; then + REPO_NAME="$2" + shift 2 + else + error "--name flag requires a value but none was provided" + exit 1 + fi + ;; + *) + error "Unknown argument: $1" + exit 1 + ;; + esac +done + +# Determine repo name +if [[ -z "$REPO_NAME" ]]; then + if git rev-parse --show-toplevel >/dev/null 2>&1; then + REPO_ROOT="$(git rev-parse --show-toplevel)" + REPO_NAME="$(basename "$REPO_ROOT")" + fi +fi + +if $LOCAL_MODE; then + log "DocC generation mode: local testing (no static hosting)" +else + log "DocC generation mode: GitHub Pages" +fi + +log "Repo name value: '${REPO_NAME}' (empty means no hosting-base-path)" + +# Load targets from .doccTargetList if present +load_from_config() { + TARGETS=$(grep -v '^\s*$' "$TARGETS_FILE" || true) + if [ -z "$TARGETS" ]; then + fatal "$TARGETS_FILE exists but contains no valid targets." + fi + for TARGET in $TARGETS; do + TARGET_FLAGS+=( --target "$TARGET" ) + done +} + +# Auto-detect documentable Swift targets +auto_detect_targets() { + if ! command -v jq >/dev/null 2>&1; then + fatal "jq is required (install with: brew install jq)" + fi + TARGETS=$(swift package dump-package \ + | jq -r '.targets[] + | select(.type == "regular" or .type == "executable") + | .name') + if [ -z "$TARGETS" ]; then + fatal "No documentable targets found in Package.swift." + fi + for TARGET in $TARGETS; do + TARGET_FLAGS+=( --target "$TARGET" ) + done +} + +# Select target source +if [ -f "$TARGETS_FILE" ]; then + log "Using targets from $TARGETS_FILE" + load_from_config +else + log "Auto-detecting Swift targets" + auto_detect_targets +fi + +# Count non-empty targets +TARGET_COUNT=$(printf "%s\n" "$TARGETS" | grep -c .) + +log "Targets detected:" +printf "%s\n" "$TARGETS" +log "Target count: $TARGET_COUNT" + +# Enable experimental combined docs when >1 target +if [ "$TARGET_COUNT" -gt 1 ]; then + COMBINED_FLAG="--enable-experimental-combined-documentation" + log "Combined documentation: enabled" +else + COMBINED_FLAG="" + log "Combined documentation: disabled" +fi + +rm -rf "$OUTPUT_DIR" +mkdir -p "$OUTPUT_DIR" + +# Generate documentation +echo +if $LOCAL_MODE; then + swift package --allow-writing-to-directory "$OUTPUT_DIR" \ + generate-documentation \ + $COMBINED_FLAG \ + "${TARGET_FLAGS[@]}" \ + --output-path "$OUTPUT_DIR" + +else + swift package --allow-writing-to-directory "$OUTPUT_DIR" \ + generate-documentation \ + $COMBINED_FLAG \ + "${TARGET_FLAGS[@]}" \ + --output-path "$OUTPUT_DIR" \ + --transform-for-static-hosting \ + ${REPO_NAME:+--hosting-base-path "$REPO_NAME"} +fi \ No newline at end of file diff --git a/scripts/run-docc-docker.sh b/scripts/run-docc-docker.sh new file mode 100755 index 0000000..b1d9ff7 --- /dev/null +++ b/scripts/run-docc-docker.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +log() { printf -- "** %s\n" "$*" >&2; } +error() { printf -- "** ERROR: %s\n" "$*" >&2; } +fatal() { error "$@"; exit 1; } + +REPO_ROOT="$(git -C "$PWD" rev-parse --show-toplevel)" +DOCC_DIR="${REPO_ROOT}/docs" +NAME="docc-server" +PORT="8080:80" + +# Validate docs directory +if ! [ -d "${DOCC_DIR}" ]; then + fatal "DocC output directory not found: ${DOCC_DIR}" +fi + +# Parse optional CLI flags +while getopts ":n:p:" flag; do + case "${flag}" in + n) NAME="${OPTARG}" ;; + p) PORT="${OPTARG}" ;; + *) ;; + esac +done + +LOCAL_PORT="${PORT%%:*}" +log "Open in browser: http://localhost:${LOCAL_PORT}/documentation/" +echo + +# Serve using Docker nginx +docker run --rm --name "${NAME}" \ + -v "${DOCC_DIR}:/usr/share/nginx/html" \ + -p "${PORT}" \ + nginx \ No newline at end of file