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
7 changes: 2 additions & 5 deletions .github/workflows/build-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,7 @@ jobs:
swift-version: "6.4.0"

- name: Install Static Linux SDK
run: |
swift sdk install \
"https://download.swift.org/swift-6.4.0-release/static-sdk/swift-6.4.0-RELEASE/swift-6.4.0-RELEASE_static-linux-0.1.0.artifactbundle.tar.gz" \
--checksum "47d2fd89eebfdf9eb4d536b6710414297f755c17926cdebc4742c08982b40a9e"
run: make install-linux-sdk

- name: Generate build metadata
uses: ./.github/actions/generate-build-metadata
Expand All @@ -144,7 +141,7 @@ jobs:
id: build-linux
run: |
set -x
swift build -c release --swift-sdk "${{ matrix.swift_sdk }}"
make build-linux SWIFT_SDK="${{ matrix.swift_sdk }}"
BIN_DIR=$(swift build -c release --swift-sdk "${{ matrix.swift_sdk }}" --show-bin-path)
BUILD_ID=$(readelf --notes "$BIN_DIR/apple-docs" | awk '/Build ID/ { print $3 }')
test -n "$BUILD_ID"
Expand Down
106 changes: 93 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ CLI_NAME := apple-docs
DIST_DIR := dist
CLI_BINARY := $(DIST_DIR)/$(CLI_NAME)
RELEASE_BIN_DIR = $(shell swift build -c release --show-bin-path)
LINUX_SWIFT_IMAGE := swift:6.4.0
LINUX_DOCKER_FLAGS ?=
LINUX_BUILD_VOLUME ?= apple-docs-cli-linux-build
LINUX_SDK_VOLUME ?= apple-docs-cli-linux-sdks
LINUX_CONTAINER = docker run --rm $(LINUX_DOCKER_FLAGS) \
--mount "type=bind,source=$(CURDIR),target=/workspace,readonly" \
--volume "$(LINUX_BUILD_VOLUME):/workspace/.build" \
--volume "$(LINUX_SDK_VOLUME):/root/.swiftpm/swift-sdks" \
--workdir /workspace $(LINUX_SWIFT_IMAGE)
LINUX_RELEASE_BIN_DIR = $(shell $(LINUX_CONTAINER) swift build -c release --show-bin-path)
INTEGRATION_FILTER ?= CLIIntegrationTests
SWIFT_SDK ?= x86_64-swift-linux-musl
# Official URL and checksum from https://www.swift.org/install/linux/.
LINUX_SDK_URL := https://download.swift.org/swift-6.4.0-release/static-sdk/swift-6.4.0-RELEASE/swift-6.4.0-RELEASE_static-linux-0.1.0.artifactbundle.tar.gz
LINUX_SDK_CHECKSUM := 47d2fd89eebfdf9eb4d536b6710414297f755c17926cdebc4742c08982b40a9e

# Source files used to determine when the distribution binary needs rebuilding
SWIFT_SOURCES := $(shell find Sources Tests -type f -name '*.swift')
Expand Down Expand Up @@ -50,6 +65,20 @@ init:
resolve:
swift package resolve

## Install the matching Swift 6.4.0 static Linux SDK
#
# Requires the Swift.org 6.4.0 toolchain, not the compiler bundled with Xcode.
.PHONY: install-linux-sdk
install-linux-sdk:
swift sdk install "$(LINUX_SDK_URL)" --checksum "$(LINUX_SDK_CHECKSUM)"

## Install the static Linux SDK in the verification container
#
# Persists the SDK in LINUX_SDK_VOLUME, without changing the host toolchain.
.PHONY: install-linux-sdk-container
install-linux-sdk-container:
$(LINUX_CONTAINER) swift sdk install "$(LINUX_SDK_URL)" --checksum "$(LINUX_SDK_CHECKSUM)"

# ============================================================================
# BUILDING & RUNNING
# ============================================================================
Expand All @@ -64,6 +93,36 @@ $(CLI_BINARY): $(SWIFT_SOURCES) $(PACKAGE_FILES) | $(DIST_DIR)
swift build -c release
cp "$(RELEASE_BIN_DIR)/$(CLI_NAME)" "$@"

## Build a static Linux release binary
#
# Run make install-linux-sdk first. Defaults to x86_64-swift-linux-musl.
# For arm64, use make build-linux SWIFT_SDK=aarch64-swift-linux-musl.
# Leaves the binary in the selected SDK's SwiftPM release output directory.
.PHONY: build-linux
build-linux:
swift build -c release --swift-sdk "$(SWIFT_SDK)"

## Build a static Linux release binary in the verification container
#
# Run make install-linux-sdk-container first. Select either architecture with SWIFT_SDK.
.PHONY: build-linux-container
build-linux-container:
$(LINUX_CONTAINER) swift build -c release --swift-sdk "$(SWIFT_SDK)" --disable-automatic-resolution

## Build the native Linux release CLI in the verification container
#
# Builds against the container's libc for native CLI integration tests.
.PHONY: build-linux-native
build-linux-native:
$(LINUX_CONTAINER) swift build -c release --disable-automatic-resolution

## Run a command in the Linux verification container
#
# For example: make run-linux ARGS="swift sdk list".
.PHONY: run-linux
run-linux:
$(LINUX_CONTAINER) $(ARGS)

## Build and run the CLI
#
# Pass command arguments through ARGS, for example:
Expand All @@ -79,29 +138,50 @@ run:
## Run all tests
#
# Executes the complete Swift Testing suite.
# Narrow a run with TEST_ARGS="--filter SuiteName".
.PHONY: test
test:
swift test
swift test $(TEST_ARGS)

## Run all tests in a Linux container
## Run Linux tests on both amd64 and arm64
#
# Uses a Docker volume for SwiftPM build output so Linux artifacts do not conflict
# with the host build directory.
# Each architecture has an isolated build volume. Both accept TEST_ARGS.
.PHONY: test-linux
test-linux:
docker run --rm \
--mount "type=bind,source=$(CURDIR),target=/workspace,readonly" \
--volume "apple-docs-cli-linux-build:/workspace/.build" \
--workdir /workspace \
swift:6.3.3 \
swift test --disable-automatic-resolution
test-linux: test-linux-amd64 test-linux-arm64

## Run tests in the amd64 Linux container
#
# Uses an isolated amd64 SwiftPM build volume. Accepts TEST_ARGS.
.PHONY: test-linux-amd64
test-linux-amd64:
$(MAKE) run-linux LINUX_DOCKER_FLAGS="$(LINUX_DOCKER_FLAGS) --platform=linux/amd64" \
LINUX_BUILD_VOLUME=apple-docs-cli-linux-amd64-build \
ARGS="swift test --disable-automatic-resolution $(TEST_ARGS)"

## Run tests in the arm64 Linux container
#
# Uses an isolated arm64 SwiftPM build volume. Accepts TEST_ARGS.
.PHONY: test-linux-arm64
test-linux-arm64:
$(MAKE) run-linux LINUX_DOCKER_FLAGS="$(LINUX_DOCKER_FLAGS) --platform=linux/arm64" \
LINUX_BUILD_VOLUME=apple-docs-cli-linux-arm64-build \
ARGS="swift test --disable-automatic-resolution $(TEST_ARGS)"

## Run live CLI integration tests
#
# Builds the release executable and runs network-dependent command tests against Apple documentation.
.PHONY: test-integration
test-integration: build
APPLE_DOCS_EXECUTABLE="$(CURDIR)/$(CLI_BINARY)" swift test --filter CLIIntegrationTests
APPLE_DOCS_EXECUTABLE="$(CURDIR)/$(CLI_BINARY)" swift test --no-parallel --filter "$(INTEGRATION_FILTER)"

## Run live release CLI tests in the Linux verification container
#
# Disables telemetry. Narrow the integration suite with INTEGRATION_FILTER=SuiteName.
.PHONY: test-integration-linux
test-integration-linux: build-linux-native
$(LINUX_CONTAINER) env TELEMETRY_DISABLED=true \
APPLE_DOCS_EXECUTABLE="$(LINUX_RELEASE_BIN_DIR)/$(CLI_NAME)" \
swift test --disable-automatic-resolution --no-parallel --filter "$(INTEGRATION_FILTER)"

## Run SwiftLint
#
Expand Down Expand Up @@ -174,7 +254,7 @@ help:
/^## / { desc = substr($$0, 4) } \
/^\.PHONY: / && desc != "" { \
target = $$2; \
printf "\033[36m%-20s\033[0m %s\n", target, desc; \
printf "\033[36m%-32s\033[0m %s\n", target, desc; \
desc = ""; target = "" \
}' $(MAKEFILE_LIST)
@echo ""
Expand Down
37 changes: 34 additions & 3 deletions docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Prerequisites

- Swift 6.3 or later and Make. CI uses Swift 6.3.3.
- Swift 6.3 or later and Make. CI and Linux containers use Swift 6.4.0.
- Homebrew for `make init`, which installs actionlint, dprint, pre-commit, and SwiftLint.
- Docker only if you want to run `make test-linux`.
- Docker for container-based Linux build and test targets.

## Build from source

Expand Down Expand Up @@ -42,12 +42,43 @@ pre-commit install
| `make run ARGS="types view Button --technology SwiftUI"` | Run the executable through SwiftPM. |
| `make build` | Build the release binary at `dist/apple-docs`. |
| `make test` | Run the test suite. |
| `make test-linux` | Run tests in a pinned Swift 6.3.3 Linux container using Docker. |
| `make test-linux` | Run tests in pinned Swift 6.4.0 containers for amd64 and arm64. |
| `make test-integration` | Build the release binary and run live tests against Apple documentation. Requires internet access. |
| `make analyze` | Run SwiftLint, formatting checks, and actionlint. |
| `make format` | Format Swift with `swift format` and JSON, YAML, Markdown, and TOML with dprint. |
| `make help` | Show all development commands. |

## Linux workflows

Container commands mount the source read-only and keep build products in Docker volumes, separate from the host build directory. The two test architectures use isolated volumes. Select one architecture or narrow the tests when needed:

```bash
make test-linux-amd64
make test-linux-arm64 TEST_ARGS="--filter AppleDocumentationClientSearchTests"
make build-linux-native
make test-integration-linux
```

Live integration tests require internet access. Both integration targets accept `INTEGRATION_FILTER=SuiteName`. `make test` also accepts `TEST_ARGS`.

For static release builds, use the matching Swift.org 6.4.0 toolchain, not Xcode's bundled compiler:

```bash
make install-linux-sdk
make build-linux SWIFT_SDK=x86_64-swift-linux-musl
make build-linux SWIFT_SDK=aarch64-swift-linux-musl
```

Alternatively, install the SDK and build inside the container without changing the host toolchain:

```bash
make install-linux-sdk-container
make build-linux-container SWIFT_SDK=x86_64-swift-linux-musl
make run-linux ARGS="swift sdk list"
```

Container targets accept `LINUX_DOCKER_FLAGS`. Direct container targets also accept `LINUX_BUILD_VOLUME` and `LINUX_SDK_VOLUME` to isolate build and SDK storage. Static outputs remain in SwiftPM's SDK-specific release directory. `make build-linux-native` uses the container's libc for release CLI integration tests.

## Before submitting

Follow the [repository instructions](../AGENTS.md), keep changes focused, and add a regression test for behavior changes and bug fixes.
Expand Down
Loading