Skip to content
Open
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
237 changes: 237 additions & 0 deletions .github/workflows/cmake_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
name: CMake Build

permissions:
contents: read

on:
workflow_call:
inputs:
cmake_version:
type: string
description: "CMake version to install and build with"
default: "4.0.3"
linux_x86_64_hash:
type: string
description: "SHA-256 of cmake-<version>-linux-x86_64.tar.gz"
default: "585ae9e013107bc8e7c7c9ce872cbdcbdff569e675b07ef57aacfb88c886faac"
linux_aarch64_hash:
type: string
description: "SHA-256 of cmake-<version>-linux-aarch64.tar.gz"
default: "391da1544ef50ac31300841caaf11db4de3976cdc4468643272e44b3f4644713"
macos_hash:
type: string
description: "SHA-256 of cmake-<version>-macos-universal.tar.gz"
default: "4e85de4daf1c3e82d7dc6b8ba5683972944b466343aeb9c327a742437bb3ce9a"
windows_x86_64_hash:
type: string
description: "SHA-256 of cmake-<version>-windows-x86_64.zip"
default: "b59a31dfbfa376a4aaea9ff560ff2b29f78ee5f9fb15447fc71ae7bf9fea9379"
windows_arm64_hash:
type: string
description: "SHA-256 of cmake-<version>-windows-arm64.zip"
default: "86ccd6485bbd4bb41a1a858db397be5bca5e0de96858bf8dbba7a64407bd6c00"
enable_linux_checks:
type: boolean
description: "Boolean to enable the Linux build. Defaults to true"
default: true
enable_macos_checks:
type: boolean
description: "Boolean to enable the macOS build (requires self-hosted runners). Defaults to false"
default: false
enable_windows_checks:
type: boolean
description: "Boolean to enable the Windows build. Defaults to true"
default: true
linux_container_image:
type: string
description: "Container image used for the Linux build"
default: "swift:6.2-jammy"
linux_prerequisites_command:
type: string
description: "Linux command to install prerequisites the install-cmake action needs (it shells out to curl)"
default: "apt-get update && apt-get install -y curl"
linux_pre_build_command:
type: string
description: "Linux command to execute before configuring the CMake project"
default: ""
linux_configure_command:
type: string
description: "Linux command to configure the CMake project"
default: "$CMAKE -G Ninja -B build -S ."
linux_build_command:
type: string
description: "Linux command to build the CMake project"
default: "$CMAKE --build build"
macos_pre_build_command:
type: string
description: "macOS command to execute before configuring the CMake project"
default: ""
macos_configure_command:
type: string
description: "macOS command to configure the CMake project"
default: "$CMAKE -G Ninja -B build -S ."
macos_build_command:
type: string
description: "macOS command to build the CMake project"
default: "$CMAKE --build build"
windows_pre_build_command:
type: string
description: |
Windows PowerShell command to execute before configuring the CMake project.
The Invoke-Program helper is available to propagate non-zero exit codes.
default: ""
windows_configure_command:
type: string
description: |
Windows PowerShell command to configure the CMake project.
The Invoke-Program helper is available to propagate non-zero exit codes.
default: "Invoke-Program cmake -G Ninja -B build -S ."
windows_build_command:
type: string
description: |
Windows PowerShell command to build the CMake project.
The Invoke-Program helper is available to propagate non-zero exit codes.
default: "Invoke-Program cmake --build build"
workflow_dispatch:

jobs:
linux-build:
name: "Linux (${{ matrix.arch }})"
if: ${{ inputs.enable_linux_checks }}
strategy:
fail-fast: false
matrix:
include:
- arch: X64
runner: ubuntu-24.04
hash: ${{ inputs.linux_x86_64_hash }}
- arch: ARM64
runner: ubuntu-24.04-arm
hash: ${{ inputs.linux_aarch64_hash }}
runs-on: ${{ matrix.runner }}
container:
image: ${{ inputs.linux_container_image }}
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install prerequisites
shell: bash
env:
PREREQUISITES_COMMAND: ${{ inputs.linux_prerequisites_command }}
run: |
set -euo pipefail
eval "${PREREQUISITES_COMMAND}"
- name: Install CMake
id: install
uses: ./.github/actions/install-cmake
with:
cmake-version: ${{ inputs.cmake_version }}
hash: ${{ matrix.hash }}
- name: Pre-build
if: ${{ inputs.linux_pre_build_command != '' }}
shell: bash
env:
CMAKE: ${{ steps.install.outputs.cmake }}
CTEST: ${{ steps.install.outputs.ctest }}
# zizmor: ignore[template-injection]
run: ${{ inputs.linux_pre_build_command }}
- name: Configure
shell: bash
env:
CMAKE: ${{ steps.install.outputs.cmake }}
CTEST: ${{ steps.install.outputs.ctest }}
# zizmor: ignore[template-injection]
run: ${{ inputs.linux_configure_command }}
- name: Build
shell: bash
env:
CMAKE: ${{ steps.install.outputs.cmake }}
CTEST: ${{ steps.install.outputs.ctest }}
# zizmor: ignore[template-injection]
run: ${{ inputs.linux_build_command }}

macos-build:
name: "macOS (ARM64)"
if: ${{ inputs.enable_macos_checks }}
runs-on: [self-hosted, macos, tahoe, ARM64]
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install CMake
id: install
uses: ./.github/actions/install-cmake
with:
cmake-version: ${{ inputs.cmake_version }}
hash: ${{ inputs.macos_hash }}
- name: Pre-build
if: ${{ inputs.macos_pre_build_command != '' }}
shell: bash
env:
CMAKE: ${{ steps.install.outputs.cmake }}
CTEST: ${{ steps.install.outputs.ctest }}
# zizmor: ignore[template-injection]
run: ${{ inputs.macos_pre_build_command }}
- name: Configure
shell: bash
env:
CMAKE: ${{ steps.install.outputs.cmake }}
CTEST: ${{ steps.install.outputs.ctest }}
# zizmor: ignore[template-injection]
run: ${{ inputs.macos_configure_command }}
- name: Build
shell: bash
env:
CMAKE: ${{ steps.install.outputs.cmake }}
CTEST: ${{ steps.install.outputs.ctest }}
# zizmor: ignore[template-injection]
run: ${{ inputs.macos_build_command }}

windows-build:
name: "Windows (${{ matrix.runner }})"
if: ${{ inputs.enable_windows_checks }}
strategy:
fail-fast: false
matrix:
include:
- runner: windows-2022
hash: ${{ inputs.windows_x86_64_hash }}
- runner: windows-11-arm
hash: ${{ inputs.windows_arm64_hash }}
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install CMake
id: install
uses: ./.github/actions/install-cmake
with:
cmake-version: ${{ inputs.cmake_version }}
hash: ${{ matrix.hash }}
- name: Pre-build
if: ${{ inputs.windows_pre_build_command != '' }}
env:
CMAKE: ${{ steps.install.outputs.cmake }}
CTEST: ${{ steps.install.outputs.ctest }}
# zizmor: ignore[template-injection]
run: |
$ErrorActionPreference = "Stop"
function Invoke-Program($Executable) { & $Executable @args; if ($LastExitCode -ne 0) { exit $LastExitCode } }
${{ inputs.windows_pre_build_command }}
- name: Configure
env:
CMAKE: ${{ steps.install.outputs.cmake }}
CTEST: ${{ steps.install.outputs.ctest }}
# zizmor: ignore[template-injection]
run: |
$ErrorActionPreference = "Stop"
function Invoke-Program($Executable) { & $Executable @args; if ($LastExitCode -ne 0) { exit $LastExitCode } }
${{ inputs.windows_configure_command }}
- name: Build
env:
CMAKE: ${{ steps.install.outputs.cmake }}
CTEST: ${{ steps.install.outputs.ctest }}
# zizmor: ignore[template-injection]
run: |
$ErrorActionPreference = "Stop"
function Invoke-Program($Executable) { & $Executable @args; if ($LastExitCode -ne 0) { exit $LastExitCode } }
${{ inputs.windows_build_command }}
10 changes: 10 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ jobs:
name: Install CMake
uses: ./.github/workflows/install_cmake_test.yml

cmake_build:
name: CMake Build
uses: ./.github/workflows/cmake_build.yml
with:
# Linux uses the default Ninja generator; install Ninja first.
linux_pre_build_command: "apt-get install -y ninja-build"
linux_configure_command: "$CMAKE -G Ninja -B build -S tests/CMakeProject"
# Windows uses CMake's default generator (MSVC), so Ninja is not required.
windows_configure_command: "Invoke-Program cmake -B build -S tests/CMakeProject"

soundness-docs:
name: "Soundness - Docs (override_target_name: ${{ matrix.override_target_name }} ; post command: ${{ matrix.post_command }})"
strategy:
Expand Down
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,56 @@ Linked PR: swiftlang/swift-syntax#2859

Enabling cross-PR testing will add about 10s to PR testing time.

### CMake Build

The `cmake_build` workflow installs a pinned CMake (using the `install-cmake`
action) and runs your configure and build commands across Linux, macOS, and
Windows. It removes the boilerplate of installing CMake and wiring up
`$CMAKE`-based build steps in each consumer.

By default it installs CMake 4.0.3, configures with
`$CMAKE -G Ninja -B build -S .`, and builds with `$CMAKE --build build`.
Linux builds run by default. macOS and Windows builds can be enabled with
`enable_macos_checks` and `enable_windows_checks` respectively. A minimal
example:

```yaml
name: Pull request

on:
pull_request:
types: [opened, reopened, synchronize]

jobs:
cmake_build:
name: CMake Build
uses: swiftlang/github-workflows/.github/workflows/cmake_build.yml@<version>
```

Override the per-platform configure and build commands to point at your
project. `$CMAKE` and `$CTEST` are exposed as environment variables, and the
installed CMake is also on `PATH`:

```yaml
with:
linux_configure_command: "$CMAKE -G Ninja -B build -S Sources -DCMAKE_BUILD_TYPE=Release"
linux_build_command: "$CMAKE --build build"
```

The default configure command uses the Ninja generator, but the workflow does
not install Ninja. Ensure Ninja is available in your environment, install it
via a `*_pre_build_command`, or override the configure command to use a
different generator:

```yaml
with:
linux_pre_build_command: "apt-get install -y ninja-build"
```

To pin a different CMake version, override `cmake_version` together with the
matching per-platform SHA-256 hashes (`linux_x86_64_hash`, `linux_aarch64_hash`,
`macos_hash`, `windows_x86_64_hash`, `windows_arm64_hash`).

### Evolution Proposal Validation

The proposal validation workflow validates added and changed proposals in a pull request to check for formatting and content errors that will cause metadata extraction to fail or be incomplete.
Expand Down
3 changes: 3 additions & 0 deletions tests/CMakeProject/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 4.0)
project(Sample C)
add_executable(sample main.c)
13 changes: 13 additions & 0 deletions tests/CMakeProject/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2026 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

int main(void) { return 0; }
Loading