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
53 changes: 43 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@ name: CI
on:
push:
branches: [ "master" ]
paths: ['.github/workflows/**', 'Package.swift', 'Scripts/**', 'Sources/**', 'Tests/**']

env:
DEVELOPER_DIR: "/Applications/Xcode_14.3.app/Contents/Developer"
DEVELOPER_DIR: "/Applications/Xcode_16.0.app/Contents/Developer"
TARGET_DEVICE: "platform=iOS Simulator,name=iPhone 16,OS=18.0"
TARGET_SCHEME: "XCTestExtension"

jobs:
test:
name: CI test
runs-on: macos-13
runs-on: macos-15

steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Run tests
run: sh ./Scripts/run_tests.sh
run: make test -s

- name: Code coverage
run: sh ./Scripts/code_coverage.sh
- name: Get coverage
run: make code-coverage -s

- name: Upload code coverage
uses: codecov/codecov-action@v3
Expand All @@ -31,6 +32,38 @@ jobs:
fail_ci_if_error: true
verbose: true

propose-next-version:
name: Propose next version
runs-on: macos-15
outputs:
next-version: ${{ steps.next-version.outputs.proposed-next-version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: '0'

- name: Get next version
id: next-version
uses: Filozoff/action-swift-propose-next-version@v1
with:
device: "${{ env.TARGET_DEVICE }}"
scheme: "${{ env.TARGET_SCHEME }}"

push-tag:
name: Create and push tag
needs: propose-next-version
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Push tag
uses: Filozoff/action-make-tag@v1
with:
commit-sha: "${{ github.sha }}"
tag: ${{ needs.propose-next-version.outputs.next-version }}
token: ${{ secrets.TAG_TOKEN }}

documentation:
name: Deploy documentation
needs: test
Expand All @@ -47,14 +80,14 @@ jobs:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

runs-on: macos-13
runs-on: macos-15

steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Build DocC
run: sh ./Scripts/make_documentation.sh
run: make documentation -s

- name: Upload artifact
uses: actions/upload-pages-artifact@v1
Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@ name: PR Check
on:
pull_request:
branches: [ "master" ]
paths: ['.github/workflows/**', 'Package.swift', 'Scripts/**', 'Sources/**', 'Tests/**']
workflow_call:

env:
DEVELOPER_DIR: "/Applications/Xcode_14.3.app/Contents/Developer"
DEVELOPER_DIR: "/Applications/Xcode_16.0.app/Contents/Developer"

jobs:
test:
name: Test
runs-on: macos-13
runs-on: macos-15

steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Run tests
run: sh ./Scripts/run_tests.sh
run: make test -s
33 changes: 33 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
build_dir := ./.build
derived_data_dir := $(build_dir)/derived_data
destination_device := platform=iOS Simulator,name=iPhone 16
documentation_output_dir := ./docs
scheme := XCTestExtension
scripts_dir := ./Scripts
test_coverage_report_dir := $(build_dir)/coverage_reports
test_output_dir := $(build_dir)/test_output
test_targets := XCTestExtensionTests

test:
echo "Testing..."
sh "$(scripts_dir)/run_tests.sh" \
--derived-data-path "$(derived_data_dir)" \
--device "$(destination_device)" \
--output "$(test_output_dir)" \
--scheme "$(scheme)"

code-coverage:
echo "Gathering code coverage..."
sh "$(scripts_dir)/code_coverage.sh" \
--derived-data-path "$(derived_data_dir)" \
--output "$(test_coverage_report_dir)" \
--test-targets "$(test_targets)"

documentation:
echo "Generating documentation..."
sh "$(scripts_dir)/make_documentation.sh" \
--derived-data-path "$(derived_data_dir)" \
--device "$(destination_device)" \
--hosting-base-path "$(scheme)" \
--output "$(documentation_output_dir)" \
--scheme "$(scheme)"
82 changes: 58 additions & 24 deletions Scripts/code_coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,71 @@ set -Eeuo pipefail

source "$(dirname "$0")"/common.sh

# CONSTANTS
# FUNCTIONS

readonly COVERAGE_DIR_NAME=".coverage"
readonly SWIFT_BUILD_DIR_NAME=".build"
readonly PACKAGE_NAME=$(swift_package_name)
readonly PROFDATA_PATH="${SWIFT_BUILD_DIR_NAME}/debug/codecov/default.profdata"
readonly BIN_PATH="${SWIFT_BUILD_DIR_NAME}/debug/${PACKAGE_NAME}PackageTests.xctest/Contents/MacOS/${PACKAGE_NAME}PackageTests"
function main() {
local profdata
local ignore_regex
local test_targets

# FUNCTIONS
IFS=',' read -r -a test_targets <<< "$TEST_TARGETS"
profdata=$(find "$DERIVED_DATA_PATH" -name "Coverage.profdata")
ignore_regex=".build|Tests"

function print_code_coverage() {
xcrun llvm-cov report \
"$BIN_PATH" \
-instr-profile="$PROFDATA_PATH" \
-ignore-filename-regex=".build|Tests" \
-use-color
}
mkdir -p "$OUTPUT_DIR"

for test_target in "${test_targets[@]}"; do
local coverage_report_path
local binary_path
local xctest_path

function export_code_coverage() {
local -r coverage_report_path="$COVERAGE_DIR_NAME/$PACKAGE_NAME.lcov"
coverage_report_path="$OUTPUT_DIR/$test_target.lcov"

mkdir -p "$COVERAGE_DIR_NAME"
printf '\n\nPreparing code coverage for %s...\n' "$test_target"

xcrun llvm-cov export \
-format="lcov" "$BIN_PATH" \
-instr-profile="$PROFDATA_PATH" \
-ignore-filename-regex=".build|Tests" \
> "$coverage_report_path"
xctest_path=$(find "$DERIVED_DATA_PATH" -name "$test_target.xctest")
if [[ -z "$xctest_path" ]]; then
echo "Error: XCTest bundle not found for target '$test_target'"
exit 1
fi

binary_path="$xctest_path/$test_target"

# Print coverage
xcrun llvm-cov report "$binary_path" \
-ignore-filename-regex="$ignore_regex" \
-instr-profile="$profdata" \
-use-color

# Export coverage
xcrun llvm-cov show "$binary_path" \
-ignore-filename-regex="$ignore_regex" \
-instr-profile="$profdata" \
> "$coverage_report_path"
done
}

# ENTRY POINT

print_code_coverage
export_code_coverage
while [[ $# -gt 0 ]]; do
case $1 in
-p| --derived-data-path)
DERIVED_DATA_PATH=${2}
shift 2
;;
-o| --output)
OUTPUT_DIR=${2}
shift 2
;;
-t| --test-targets)
TEST_TARGETS=${2}
shift 2
;;
*)
echo "Unknown argument: '${1}'"
exit 1
;;
esac
done

main
69 changes: 50 additions & 19 deletions Scripts/make_documentation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,62 @@ set -Eeuo pipefail

source "$(dirname "$0")"/common.sh

# CONSTANTS
# FUNCTIONS

readonly DOCS_PATH="./docs"
readonly PACKAGE_NAME=$(swift_package_name)
function main() {
local -r docs_index_path="$OUTPUT_DIR/index.html"
local -r package_path_element=$(lowercase "$SCHEME")
local docc_archive_path

# FUNCTIONS
echo "Creating doccarchive..."
xcodebuild \
-derivedDataPath "$DERIVED_DATA_PATH" \
-destination "$DESTINATION" \
-scheme "$SCHEME" \
docbuild | xcbeautify
echo "Done!"

function create_documentation() {
local -r docs_index_path="$DOCS_PATH/index.html"
local -r package_path_element=$(lowercase "$PACKAGE_NAME")

echo "$package_path_element"
swift package \
--allow-writing-to-directory "$DOCS_PATH" \
generate-documentation \
--disable-indexing \
--hosting-base-path "$PACKAGE_NAME" \
--include-extended-types \
--output-path "$DOCS_PATH" \
--target "$PACKAGE_NAME" \
--transform-for-static-hosting
docc_archive_path=$(find "$DERIVED_DATA_PATH" -name "$SCHEME.doccarchive")
echo "DocC archive found at path '$docc_archive_path'."

echo "Converting doccarchive to static HTML..."
"$(xcrun --find docc)" process-archive transform-for-static-hosting "$docc_archive_path" \
--hosting-base-path "$HOSTING_BASE_PATH" \
--output-path "$OUTPUT_DIR"

echo "<script>window.location.href += \"/documentation/$package_path_element\"</script>" > "$docs_index_path"
echo "Done!"
}

# ENTRY POINT

create_documentation
while [[ $# -gt 0 ]]; do
case $1 in
-b| --hosting-base-path)
HOSTING_BASE_PATH=${2}
shift 2
;;
-d| --device)
DESTINATION=${2}
shift 2
;;
-p| --derived-data-path)
DERIVED_DATA_PATH=${2}
shift 2
;;
-o| --output)
OUTPUT_DIR=${2}
shift 2
;;
-s| --scheme)
SCHEME=${2}
shift 2
;;
*)
echo "Unknown argument: '${1}'"
exit 1
;;
esac
done

main
37 changes: 36 additions & 1 deletion Scripts/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,45 @@ function package_clean() {
}

function swift_test() {
swift test --enable-code-coverage 2>&1 | xcpretty
xcodebuild \
-default-test-execution-time-allowance 5 \
-derivedDataPath "${DERIVED_DATA_PATH}" \
-destination "${DESTINATION}" \
-enableCodeCoverage "YES" \
-jobs 4 \
-parallel-testing-enabled "YES" \
-resultBundlePath "${OUTPUT}" \
-scheme "${SCHEME}" \
-test-timeouts-enabled "YES" \
test | xcbeautify
}

# ENTRY POINT

while [[ $# -gt 0 ]]; do
case $1 in
-d| --device)
DESTINATION=${2}
shift 2
;;
-o| --output)
OUTPUT=${2}
shift 2
;;
-p| --derived-data-path)
DERIVED_DATA_PATH=${2}
shift 2
;;
-s| --scheme)
SCHEME=${2}
shift 2
;;
*)
echo "Unknown argument: '${1}'"
exit 1
;;
esac
done

package_clean
swift_test
Loading