Skip to content

Commit acd2823

Browse files
authored
Merge branch 'swiftlang:main' into main
2 parents be91e12 + a28eb2c commit acd2823

14 files changed

+1491
-39
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Create automerge PR
2+
3+
# Merges `head_branch` into `base_branch` and opens a PR to incorporate that merge commit into `base_branch`.
4+
#
5+
# The typical use case for this is in the first period after Swift has cut release branches.
6+
# Some repositories want to include most changes from `main` also in the release branch. When this job is set up, it can automatically create PRs to merge `main` into the release branch.
7+
# Maintainers of the package can then inspect the changes to ensure that they are not too risky for the release branch.
8+
# We will also run the normal PR testing on these changes, ensuring that these modifications don't break the build.
9+
#
10+
# Example usage in a repository:
11+
#
12+
# ```
13+
# name: Create PR to merge main into release branch
14+
#
15+
# # In the first period after branching the release branch, we typically want to include all changes from `main` also in the release branch. This workflow automatically creates a PR every Monday to merge main into the release branch.
16+
# # Later in the release cycle we should stop this practice to avoid landing risky changes by disabling this workflow. To do so, disable the workflow as described in https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/disabling-and-enabling-a-workflow
17+
#
18+
# on:
19+
# schedule:
20+
# - cron: '0 9 * * MON'
21+
# workflow_dispatch:
22+
#
23+
# jobs:
24+
# create_merge_pr:
25+
# name: Create PR to merge main into release branch
26+
# uses: swiftlang/github-workflows/.github/workflows/create_automerge_pr.yml@main
27+
# if: (github.event_name == 'schedule' && github.repository == 'swiftlang/swift-format') || (github.event_name != 'schedule') # Ensure that we don't run this on a schedule in a fork
28+
# permissions:
29+
# contents: write
30+
# pull-requests: write
31+
# with:
32+
# base_branch: release/6.2
33+
# ```
34+
#
35+
# PRs created by GitHub Actions don't kick off further actions (https://github.com/peter-evans/create-pull-request/blob/d57e551ebc1a16dee0b8c9ea6d24dba7627a6e35/docs/concepts-guidelines.md#triggering-further-workflow-runs).
36+
# As a workaround, we mark automerge PRs that are created by GitHub actions as draft and trigger the GitHub actions by marking the PR as ready for review. `ready_for_review` must be added to the PR types for this purpose, eg.
37+
# ```
38+
# on:
39+
# pull_request:
40+
# types: [..., ready_for_review]
41+
# ```
42+
# Unfortunately this will also re-trigger testing evenon a normal user's PR (which may have already been tested), but skipping them causes the checks to reset so this is the best we can do for now.
43+
on:
44+
workflow_call:
45+
inputs:
46+
base_branch:
47+
type: string
48+
description: The branch into which head_branch should be merged
49+
required: true
50+
head_branch:
51+
type: string
52+
description: The branch that should be merged into base_branch
53+
default: main
54+
pr_message:
55+
type: string
56+
description: The message that should be included in the PR created by this job
57+
default: This PR was automatically opened by a GitHub action. Review the changes included in this PR and determine if they should be included in the release branch. If yes, merge the PR. Otherwise revert changes that should not be included on this branch.
58+
59+
jobs:
60+
create_merge_pr:
61+
name: Create PR to merge ${{ inputs.head_branch }} into ${{ inputs.base_branch }} branch
62+
runs-on: ubuntu-latest
63+
permissions:
64+
contents: write
65+
pull-requests: write
66+
steps:
67+
- name: Checkout repository
68+
uses: actions/checkout@v4
69+
with:
70+
fetch-depth: 0
71+
- name: Check if there are commits to merge
72+
id: create_merge_commit
73+
run: |
74+
# Without this, we can't perform git operations in GitHub actions.
75+
git config --global --add safe.directory "$(realpath .)"
76+
git config --local user.name 'swift-ci'
77+
git config --local user.email '[email protected]'
78+
79+
if [[ "$(git rev-list --left-only --count origin/${{ inputs.head_branch }}...origin/${{ inputs.base_branch }})" == 0 ]]; then
80+
echo "Nothing to merge"
81+
echo "has_commits_to_merge=false" >> "$GITHUB_OUTPUT"
82+
exit
83+
fi
84+
85+
echo "has_commits_to_merge=true" >> "$GITHUB_OUTPUT"
86+
- name: Push branch and create PR
87+
id: push_branch
88+
if: ${{ steps.create_merge_commit.outputs.has_commits_to_merge == 'true' }}
89+
env:
90+
GH_TOKEN: ${{ github.token }}
91+
run: |
92+
# Create a branch for the PR instead of opening a PR that merges head_branch directly so that we have a fixed
93+
# target in the PR and don't modify the PR as new commits are put on the head branch.
94+
PR_BRANCH="automerge/merge-main-$(date +%Y-%m-%d_%H-%M)"
95+
git checkout ${{ inputs.head_branch }}
96+
git checkout -b "$PR_BRANCH"
97+
git push --set-upstream origin "$PR_BRANCH"
98+
99+
gh pr create \
100+
--base "${{ inputs.base_branch }}" \
101+
--head "$PR_BRANCH" \
102+
--title 'Merge `${{ inputs.head_branch }}` into `${{ inputs.base_branch }}`' \
103+
--body '${{ inputs.pr_message }}' \
104+
--draft
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
name: Performance test
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
container:
7+
type: string
8+
description: "The container that the performance tests should run in"
9+
default: "swift:latest"
10+
package_path:
11+
type: string
12+
description: The directory in the repository that contains a package, which depends on ordo-one/package-benchmark and can run performance measurements.
13+
default: Benchmarks
14+
comment_header:
15+
type: string
16+
description: |
17+
If the performance has changed, this text will be prepended to the comment that contains the performance measurements.
18+
This can be either for performance improvements or regressions.
19+
default: |
20+
This PR has changed performance characteristics. Please review that the measurements reported below are expected. If these are improvements, thanks for improving the performance.
21+
22+
jobs:
23+
measure_performance:
24+
name: Measure performance
25+
runs-on: ubuntu-latest
26+
container:
27+
image: ${{ inputs.container }}
28+
timeout-minutes: 60
29+
permissions:
30+
pull-requests: write
31+
steps:
32+
- name: Install libjemalloc-dev
33+
run: apt-get update && apt-get install -y libjemalloc-dev
34+
- name: Checkout repository
35+
uses: actions/checkout@v4
36+
with:
37+
fetch-depth: 0
38+
- name: Mark the workspace as safe
39+
# https://github.com/actions/checkout/issues/766
40+
run: git config --global --add safe.directory ${GITHUB_WORKSPACE}
41+
- name: Measure PR performance
42+
run: |
43+
swift package --package-path ${{ inputs.package_path }} --allow-writing-to-directory ${{ inputs.package_path }}/.benchmarkBaselines/ benchmark baseline update "${{ github.head_ref }}"
44+
- name: Measure base branch performance
45+
run: |
46+
git checkout ${{ github.base_ref }}
47+
swift package --package-path ${{ inputs.package_path }} --allow-writing-to-directory ${{ inputs.package_path }}/.benchmarkBaselines/ benchmark baseline update "${{ github.base_ref }}"
48+
- name: Compare performance measurements
49+
id: compare_performance
50+
run: |
51+
if ! swift package --package-path ${{ inputs.package_path }} benchmark baseline check "${{ github.base_ref }}" "${{ github.head_ref }}" --format markdown > /tmp/comparison.md 2>/tmp/comparison-stderr.txt; then
52+
echo "has_significant_changes=true" >> "$GITHUB_OUTPUT"
53+
else
54+
echo "has_significant_changes=false" >> "$GITHUB_OUTPUT"
55+
fi
56+
- name: Install gh
57+
if: ${{ steps.compare_performance.outputs.has_significant_changes == 'true' }}
58+
# Installation instructions from https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian-ubuntu-linux-raspberry-pi-os-apt
59+
run: |
60+
(type -p wget >/dev/null || (apt update && apt-get install wget -y))
61+
mkdir -p -m 755 /etc/apt/keyrings
62+
out=$(mktemp)
63+
wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg
64+
cat $out | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null
65+
chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg
66+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null
67+
apt update
68+
apt install gh -y
69+
- name: Post comment
70+
if: ${{ steps.compare_performance.outputs.has_significant_changes == 'true' }}
71+
env:
72+
GH_TOKEN: ${{ github.token }}
73+
run: |
74+
if grep benchmarkThresholdRegression /tmp/comparison-stderr.txt > /dev/null; then
75+
PERFORMANCE_CHANGE_MESSAGE="This PR has regressed performance characteristics. Please review whether the changes reported below are expected or if you can do something to improve them."
76+
elif grep benchmarkThresholdImprovement /tmp/comparison-stderr.txt > /dev/null; then
77+
PERFORMANCE_CHANGE_MESSAGE="This PR has improved performance characteristics. Thank you 🚀"
78+
else
79+
PERFORMANCE_CHANGE_MESSAGE="This PR has changed performance characteristics. Please review that the measurements reported below are expected or if you can do something to improve them."
80+
fi
81+
82+
cat > /tmp/performance_change_header.md <<EOF
83+
$PERFORMANCE_CHANGE_MESSAGE
84+
85+
<details><summary><b>Performance report</b></summary>
86+
87+
EOF
88+
89+
echo "</details>" > /tmp/performance_change_footer.md
90+
91+
COMMENT="$(cat /tmp/performance_change_header.md /tmp/comparison.md /tmp/performance_change_footer.md)"
92+
gh pr comment ${{ github.event.number }} --body "$COMMENT"

.github/workflows/pull_request.yml

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,48 @@ on:
55
types: [opened, reopened, synchronize]
66

77
jobs:
8+
tests_with_docker_embedded_swift:
9+
name: Test Embedded Swift SDKs
10+
uses: ./.github/workflows/swift_package_test.yml
11+
with:
12+
# Wasm
13+
enable_linux_checks: false
14+
enable_macos_checks: false
15+
enable_windows_checks: false
16+
wasm_sdk_pre_build_command: |
17+
mkdir MyPackage
18+
cd MyPackage
19+
swift package init --type library
20+
enable_embedded_wasm_sdk_build: true
21+
822
tests_with_docker:
923
name: Test with Docker
1024
uses: ./.github/workflows/swift_package_test.yml
1125
with:
1226
# Linux
27+
linux_os_versions: '["jammy", "rhel-ubi9", "amazonlinux2"]'
1328
linux_build_command: |
1429
mkdir MyPackage
1530
cd MyPackage
1631
swift package init --type library
1732
swift build
33+
linux_static_sdk_pre_build_command: |
34+
mkdir MyPackage
35+
cd MyPackage
36+
swift package init --type library
37+
enable_linux_static_sdk_build: true
38+
# Wasm
39+
wasm_sdk_pre_build_command: |
40+
mkdir MyPackage
41+
cd MyPackage
42+
swift package init --type library
43+
enable_wasm_sdk_build: true
1844
# Windows
1945
windows_build_command: |
2046
mkdir MyPackage
2147
cd MyPackage
22-
swift package init --type library
23-
swift build
48+
Invoke-Program swift package init --type library
49+
Invoke-Program swift build
2450
enable_windows_docker: true
2551

2652
tests_without_docker:
@@ -33,14 +59,27 @@ jobs:
3359
windows_build_command: |
3460
mkdir MyPackage
3561
cd MyPackage
36-
swift package init --type library
37-
swift build
62+
Invoke-Program swift package init --type library
63+
Invoke-Program swift build
3864
enable_windows_docker: false
3965

66+
tests_macos:
67+
name: Test
68+
uses: ./.github/workflows/swift_package_test.yml
69+
with:
70+
enable_linux_checks: false
71+
enable_windows_checks: false
72+
# macOS
73+
enable_macos_checks: true
74+
macos_build_command: |
75+
mkdir MyPackage
76+
cd MyPackage
77+
xcrun swift package init --type library
78+
xcrun swift build
79+
4080
soundness:
4181
name: Soundness
4282
uses: ./.github/workflows/soundness.yml
4383
with:
4484
api_breakage_check_enabled: false
4585
license_header_check_project_name: "Swift.org"
46-
format_check_enabled: false

.github/workflows/scripts/check-docs.sh

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,29 @@ if [ -z "$package_files" ]; then
3131
fatal "Package.swift not found. Please ensure you are running this script from the root of a Swift package."
3232
fi
3333

34-
for package_file in $package_files; do
35-
log "Editing $package_file..."
36-
cat <<EOF >> "$package_file"
34+
# yq 3.1.0-3 doesn't have filter, otherwise we could replace the grep call with "filter(.identity == "swift-docc-plugin") | keys | .[]"
35+
hasDoccPlugin=$(swift package dump-package | yq -r '.dependencies[].sourceControl' | grep -e "\"identity\": \"swift-docc-plugin\"" || true)
36+
if [[ -n $hasDoccPlugin ]]
37+
then
38+
log "swift-docc-plugin already exists"
39+
else
40+
log "Appending swift-docc-plugin"
41+
for package_file in $package_files; do
42+
log "Editing $package_file..."
43+
cat <<EOF >> "$package_file"
3744
3845
package.dependencies.append(
39-
.package(url: "https://github.com/swiftlang/swift-docc-plugin", "1.0.0"..<"1.4.0")
46+
.package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.0.0")
4047
)
4148
EOF
42-
done
49+
done
50+
fi
4351

4452
log "Checking documentation targets..."
4553
for target in $(yq -r '.builder.configs[].documentation_targets[]' .spi.yml); do
4654
log "Checking target $target..."
4755
# shellcheck disable=SC2086 # We explicitly want to explode "$ADDITIONAL_DOCC_ARGUMENTS" into multiple arguments.
48-
swift package plugin generate-documentation --target "$target" --warnings-as-errors --analyze --level detailed $ADDITIONAL_DOCC_ARGUMENTS
56+
swift package plugin generate-documentation --target "$target" --warnings-as-errors --analyze $ADDITIONAL_DOCC_ARGUMENTS
4957
done
5058

5159
log "✅ Found no documentation issues."

.github/workflows/scripts/check-license-header.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,14 @@ while IFS= read -r file_path; do
6666
bazelrc) comment_marker='##' ;;
6767
bzl) comment_marker='##' ;;
6868
c) comment_marker='//' ;;
69+
cpp) comment_marker='//' ;;
6970
cmake) comment_marker='##' ;;
7071
code-workspace) continue ;; # VS Code workspaces are JSON and shouldn't contain comments
7172
CODEOWNERS) continue ;; # Doesn't need a license header
7273
Dockerfile) comment_marker='##' ;;
7374
editorconfig) comment_marker='##' ;;
7475
flake8) continue ;; # Configuration file doesn't need a license header
76+
gitattributes) continue ;; # Configuration files don't need license headers
7577
gitignore) continue ;; # Configuration files don't need license headers
7678
gradle) comment_marker='//' ;;
7779
groovy) comment_marker='//' ;;
@@ -92,13 +94,16 @@ while IFS= read -r file_path; do
9294
py) comment_marker='##'; header_prefix=$'#!/usr/bin/env python3\n' ;;
9395
rb) comment_marker='##'; header_prefix=$'#!/usr/bin/env ruby\n' ;;
9496
sh) comment_marker='##'; header_prefix=$'#!/bin/bash\n' ;;
97+
strings) comment_marker='//' ;;
9598
swift-format) continue ;; # .swift-format is JSON and doesn't support comments
9699
swift) comment_marker='//' ;;
97100
ts) comment_marker='//' ;;
98101
tsx) comment_marker='//' ;;
99102
txt) continue ;; # Text files don't need license headers
100103
yml) continue ;; # YAML Configuration files don't need license headers
101104
yaml) continue ;; # YAML Configuration files don't need license headers
105+
xcbuildrules) comment_marker='//' ;;
106+
xcspec) comment_marker='//' ;;
102107
*)
103108
error "Unsupported file extension ${file_extension} for file (exclude or update this script): ${file_path}"
104109
paths_with_missing_license+=("${file_path} ")

0 commit comments

Comments
 (0)