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
50 changes: 50 additions & 0 deletions .github/actions/install-cmake/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: 'Install CMake'
description: 'Download and install CMake'

inputs:
cmake-version:
description: "CMake version (e.g. '3.30.2')"
required: true
hash:
description: "Expected SHA-256 hash of the target archive (Required)."
required: true
install_dir:
description: "Location where to install CMake"
required: false
default: ""

outputs:
cmake-dir:
description: "Directory containing the CMake binaries"
value: ${{ steps.install.outputs.cmake-dir }}
cmake:
description: "Path to the installed CMake binary"
value: ${{ steps.install.outputs.cmake-path }}
ctest:
description: "Path to the installed CTest binary"
value: ${{ steps.install.outputs.ctest-path }}

runs:
using: "composite"
steps:
- name: Run CMake Installer
id: install
shell: bash
env:
CMAKE_VERSION: ${{ inputs.cmake-version }}
CMAKE_SHA256: ${{ inputs.hash }}
CMAKE_INSTALL_DIR: ${{ inputs.install_dir }}
RAW_ACTION_PATH: ${{ github.action_path }}
run: |
# Resolve path whether running on the host runner or inside a Docker container
SCRIPT_PATH="${RAW_ACTION_PATH}/install-cmake.sh"
if [ ! -f "${SCRIPT_PATH}" ]; then
CONTAINER_PATH="$(echo "${RAW_ACTION_PATH}" | sed 's|^/home/runner/work|/__w|')"
if [ -f "${CONTAINER_PATH}/install-cmake.sh" ]; then
SCRIPT_PATH="${CONTAINER_PATH}/install-cmake.sh"
elif [ -f "${GITHUB_WORKSPACE}/.github/actions/install-cmake/install-cmake.sh" ]; then
SCRIPT_PATH="${GITHUB_WORKSPACE}/.github/actions/install-cmake/install-cmake.sh"
fi
fi

bash "${SCRIPT_PATH}"
102 changes: 102 additions & 0 deletions .github/actions/install-cmake/install-cmake.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the Swift.org open source project
##
## Copyright (c) YEARS 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
##
##===----------------------------------------------------------------------===##
set -euo pipefail

VERSION="${CMAKE_VERSION:?CMAKE_VERSION is required}"
EXPECTED_SHA="${CMAKE_SHA256:?CMAKE_SHA256 is required}"
OS="${RUNNER_OS:?RUNNER_OS is required}"
ARCH="${RUNNER_ARCH:?RUNNER_ARCH is required}"
TEMP_DIR="${RUNNER_TEMP:?RUNNER_TEMP is required}"

# Normalize hash to lowercase and strip whitespace
EXPECTED_SHA=$(echo "${EXPECTED_SHA}" | tr '[:upper:]' '[:lower:]' | xargs)

# 1. Determine destination directory (fallback to $RUNNER_TEMP/cmake-<version> if unset/empty)
DEST_DIR="${CMAKE_INSTALL_DIR:-}"
if [ -z "${DEST_DIR}" ]; then
DEST_DIR="${TEMP_DIR}/cmake-${VERSION}"
fi

# 2. Determine archive filename, binary subpath, and binary extension
BIN_EXT=""
case "${OS}" in
Linux)
case "${ARCH}" in
X64) ARCH_NAME="x86_64" ;;
ARM64) ARCH_NAME="aarch64" ;;
*) echo "::error::Unsupported Linux architecture: ${ARCH}"; exit 1 ;;
esac
ARCHIVE="cmake-${VERSION}-linux-${ARCH_NAME}.tar.gz"
BIN_SUBPATH="bin"
;;
macOS)
ARCHIVE="cmake-${VERSION}-macos-universal.tar.gz"
BIN_SUBPATH="CMake.app/Contents/bin"
;;
Windows)
case "${ARCH}" in
X64) ARCH_NAME="x86_64" ;;
ARM64) ARCH_NAME="arm64" ;;
*) echo "::error::Unsupported Windows architecture: ${ARCH}"; exit 1 ;;
esac
ARCHIVE="cmake-${VERSION}-windows-${ARCH_NAME}.zip"
BIN_SUBPATH="bin"
BIN_EXT=".exe"
;;
*)
echo "::error::Unsupported OS: ${OS}"
exit 1
;;
esac

ARCHIVE_URL="https://github.com/Kitware/CMake/releases/download/v${VERSION}/${ARCHIVE}"
ARCHIVE_PATH="${TEMP_DIR}/${ARCHIVE}"

# 3. Download
echo "==> Downloading ${ARCHIVE_URL}..."
curl -fsSL --retry 3 -o "${ARCHIVE_PATH}" "${ARCHIVE_URL}"

# 4. Verify SHA-256 directly in one step
echo "==> Verifying SHA-256..."
CHECK_CMD=$(command -v sha256sum || echo "shasum -a 256")
echo "${EXPECTED_SHA} ${ARCHIVE_PATH}" | ${CHECK_CMD} -c -

# 5. Extract into destination directory
echo "==> Extracting into ${DEST_DIR}..."
mkdir -p "${DEST_DIR}"

if [[ "${ARCHIVE}" == *.tar.gz ]]; then
tar -xzf "${ARCHIVE_PATH}" -C "${DEST_DIR}" --strip-components=1
elif [[ "${ARCHIVE}" == *.zip ]]; then
UNZIP_TEMP="${TEMP_DIR}/unzip_tmp"
mkdir -p "${UNZIP_TEMP}"
unzip -q -o "${ARCHIVE_PATH}" -d "${UNZIP_TEMP}"
TOP_DIR=$(find "${UNZIP_TEMP}" -mindepth 1 -maxdepth 1 -type d)
mv "${TOP_DIR}"/* "${DEST_DIR}/"
rm -rf "${UNZIP_TEMP}"
fi
rm -f "${ARCHIVE_PATH}"

# 6. Set PATH and GITHUB_OUTPUT
CMAKE_BIN_DIR="${DEST_DIR}/${BIN_SUBPATH}"
echo "${CMAKE_BIN_DIR}" >> "${GITHUB_PATH}"

if [ -n "${GITHUB_OUTPUT:-}" ]; then
{
echo "cmake-dir=${CMAKE_BIN_DIR}"
echo "cmake-path=${CMAKE_BIN_DIR}/cmake${BIN_EXT}"
echo "ctest-path=${CMAKE_BIN_DIR}/ctest${BIN_EXT}"
} >> "${GITHUB_OUTPUT}"
fi

echo "==> CMake ${VERSION} successfully installed at ${CMAKE_BIN_DIR}"
47 changes: 47 additions & 0 deletions .github/actions/install-cmake/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Install CMake

Install an arbitrary version of CMake.

Inputs:
- cmake-version: Version of CMake to install (e.g. 3.30.2)
- hash: sha256 of the downloaded artifact (.zip or .tar.gz)
- intall_dir: (optional) location where to install CMake

Outputs:
- cmake-dir: Directory containing the CMake binaries
- cmake: Path to the installed CMake binary
- ctest: Path to the installed CTest binary


## Usage

```yaml
...

steps:

...

- name: Install CMake
id: install-cmake
uses: swiftlang/github-workflows/.github/actions/install-cmake@<version>
with:
cmake-version: 4.0.3
hash: 585ae9e013107bc8e7c7c9ce872cbdcbdff569e675b07ef57aacfb88c886faac

- name: Run Build
shell: bash
env:
CMAKE: ${{ steps.install-cmake.outputs.cmake }}
run: |
"$CMAKE" -G Ninja -B build -S <sources> -DCMAKE_BUILD_TYPE=Release

- name: Run Tests
shell: bash
env:
CTEST: ${{ steps.install-cmake.outputs.ctest }}
run: |
"$CTEST" --output-on-failure --test-timeout 150 --test-dir build -j

...
```