From 0b820a2fcb4f29ffe23269d610c7f6e4572763d8 Mon Sep 17 00:00:00 2001 From: Nikolai Guyot <32816085+PoshAlpaca@users.noreply.github.com> Date: Sat, 29 Jan 2022 20:10:51 +0100 Subject: [PATCH] Add macOS support (#11) * Determine cache config based on platform * Add installation for macOS * Clean up scripts Co-authored-by: Moritz Lang --- .github/workflows/ci.yaml | 4 +- README.md | 4 +- action.yaml | 28 ++++- install-swift.sh | 221 ++++++++++++++++++++++++++++++-------- 4 files changed, 205 insertions(+), 52 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 835a037..2d44747 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,8 +8,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-18.04, ubuntu-20.04] - swift: [5.5, swift-DEVELOPMENT-SNAPSHOT-2021-11-12-a] + os: [ubuntu-18.04, ubuntu-20.04, macos-latest] + swift: [5.5, swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a] runs-on: ${{ matrix.os }} steps: diff --git a/README.md b/README.md index be16889..e824836 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,9 @@ jobs: strategy: matrix: swift: [5.5, swift-DEVELOPMENT-SNAPSHOT-2021-11-12-a] - ubuntu: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-18.04, ubuntu-20.04, macos-latest] fail-fast: false - runs-on: ${{ matrix.ubuntu }} + runs-on: ${{ matrix.os }} steps: - name: Install Swift uses: slashmo/install-swift@v0.1.0 diff --git a/action.yaml b/action.yaml index 013b57e..ef40f0a 100644 --- a/action.yaml +++ b/action.yaml @@ -9,19 +9,37 @@ inputs: runs: using: "composite" steps: - - name: Determine Ubuntu Version + - name: Determine Cache Options run: | - UBUNTU_VERSION=$(lsb_release -rs) + # ubuntu-20.04-5.5 + # macos-12.2-5.5 - echo "UBUNTU_VERSION=$UBUNTU_VERSION" >> $GITHUB_ENV + SWIFT_VERSION=${{ inputs.version }} + + if [[ $SWIFT_VERSION == swift-DEVELOPMENT-SNAPSHOT* ]]; then + RELEASE_NAME=$SWIFT_VERSION + else + RELEASE_NAME=swift-$SWIFT_VERSION-RELEASE + fi + + if [ $RUNNER_OS == Linux ]; then + PLATFORM=ubuntu-$(lsb_release -rs) + TOOLCHAIN_CACHE_PATH=/opt/swift-toolchains/$RELEASE_NAME + elif [ $RUNNER_OS == macOS ]; then + PLATFORM=macos-$(sw_vers -productVersion) + TOOLCHAIN_CACHE_PATH=${HOME}/Library/Developer/Toolchains/$RELEASE_NAME.xctoolchain + fi + + echo "TOOLCHAIN_CACHE_PATH=$TOOLCHAIN_CACHE_PATH" >> $GITHUB_ENV + echo "TOOLCHAIN_CACHE_KEY=$PLATFORM-$SWIFT_VERSION" >> $GITHUB_ENV shell: bash - name: Cache Swift Toolchain id: swift-toolchain-cache uses: actions/cache@v2 with: - path: /usr/share/swift-toolchain - key: ubuntu-${{ env.UBUNTU_VERSION }}-${{ inputs.version }} + path: ${{ env.TOOLCHAIN_CACHE_PATH }} + key: ${{ env.TOOLCHAIN_CACHE_KEY }} - name: Install Swift Toolchain run: SWIFT_VERSION=${{ inputs.version }} $GITHUB_ACTION_PATH/install-swift.sh diff --git a/install-swift.sh b/install-swift.sh index ecc6d1d..185b1b0 100755 --- a/install-swift.sh +++ b/install-swift.sh @@ -1,54 +1,189 @@ #!/bin/bash -if [[ $SWIFT_VERSION == swift-DEVELOPMENT-SNAPSHOT* ]]; then - TOOLCHAIN_BASE_URL="https://download.swift.org/development/ubuntu${UBUNTU_VERSION//[.]/}/$SWIFT_VERSION" - TOOLCHAIN_PATH="$SWIFT_VERSION-ubuntu$UBUNTU_VERSION" -else - TOOLCHAIN_BASE_URL="https://download.swift.org/swift-$SWIFT_VERSION-release/ubuntu${UBUNTU_VERSION//[.]/}/swift-$SWIFT_VERSION-RELEASE" - TOOLCHAIN_PATH="swift-$SWIFT_VERSION-RELEASE-ubuntu$UBUNTU_VERSION" -fi - -TOOLCHAIN_TAR="$TOOLCHAIN_PATH.tar.gz" -TOOLCHAIN_SIG="$TOOLCHAIN_TAR.sig" -TOOLCHAIN_TAR_URL="$TOOLCHAIN_BASE_URL/$TOOLCHAIN_TAR" -TOOLCHAIN_SIG_URL="$TOOLCHAIN_BASE_URL/$TOOLCHAIN_SIG" - -echo "Installing system dependencies for '$UBUNTU_VERSION' 📦" -sudo apt-get update -if [ $UBUNTU_VERSION == "18.04" ]; then - sudo apt-get install \ - binutils git libc6-dev libcurl4 libedit2 libgcc-5-dev libpython2.7 libsqlite3-0 libstdc++-5-dev libxml2 \ - pkg-config tzdata zlib1g-dev -elif [ $UBUNTU_VERSION == "20.04" ]; then - sudo apt-get install \ - binutils git gnupg2 libc6-dev libcurl4 libedit2 libgcc-9-dev libpython2.7 libsqlite3-0 libstdc++-9-dev libxml2 \ - libz3-dev pkg-config tzdata uuid-dev zlib1g-dev -else - echo "No Swift Toolchain available for Ubuntu version '$UBUNTU_VERSION'." - echo "Visit https://swift.org/download for more information." - exit 1; -fi - -if [ -d "/usr/share/swift-toolchain" ]; then - echo "Toolchain already exists, skipping download ✅" -else - echo "Reading toolchain version from .swift-version 📄" - echo "Detected Swift toolchain version '$(cat .swift-version)' 📄" +# Expects environment variable `SWIFT_VERSION` +# Example values: 5.5 or swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a +# System library dependencies: wget + +install_swift () { + determine_os + + if [[ -d $(toolchain_path) ]]; then + echo "Toolchain already exists, skipping download ✅" + else + download_toolchain + if_linux_verify_signature + if_macos_run_installer + fi + + if_linux_install_system_dependencies + install_toolchain + + echo "Successfully installed Swift toolchain 🎉" +} + +#-=============================================================================- +# Steps +#-=============================================================================- + +determine_os () { + KERNEL=$(uname) + if [[ $KERNEL == "Darwin" ]]; then + IS_MACOS=true + elif [[ $KERNEL == "Linux" ]]; then + IS_LINUX=true + UBUNTU_VERSION=$(lsb_release -rs) + else + echo "Unsupported kernel '$KERNEL' ☠️" + exit 1; + fi +} + +download_toolchain () { echo "Downloading Swift toolchain ☁️" - wget $TOOLCHAIN_TAR_URL + if [ $IS_MACOS ]; then + TOOLCHAIN_URL=$(download_url pkg) + elif [ $IS_LINUX ]; then + TOOLCHAIN_URL=$(download_url tar.gz) + fi + + wget $TOOLCHAIN_URL +} + +if_linux_install_system_dependencies () { + if ! [[ $IS_LINUX ]]; then + return 0; + fi + + echo "Installing system dependencies for '$UBUNTU_VERSION' 📦" + sudo apt-get update + if [ $UBUNTU_VERSION == "18.04" ]; then + sudo apt-get install \ + binutils git libc6-dev libcurl4 libedit2 libgcc-5-dev libpython2.7 libsqlite3-0 libstdc++-5-dev libxml2 \ + pkg-config tzdata zlib1g-dev + elif [ $UBUNTU_VERSION == "20.04" ]; then + sudo apt-get install \ + binutils git gnupg2 libc6-dev libcurl4 libedit2 libgcc-9-dev libpython2.7 libsqlite3-0 libstdc++-9-dev libxml2 \ + libz3-dev pkg-config tzdata uuid-dev zlib1g-dev + else + echo "No Swift Toolchain available for Ubuntu version '$UBUNTU_VERSION'." + echo "Visit https://swift.org/download for more information." + exit 1 + fi +} + +if_linux_verify_signature () { + if ! [[ $IS_LINUX ]]; then + return 0; + fi echo "Verifying Swift toolchain 🔑" wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - - wget $TOOLCHAIN_SIG_URL - gpg --verify $TOOLCHAIN_SIG + wget $(download_url tar.gz.sig) + gpg --verify $(download_file tar.gz.sig) +} +if_macos_run_installer () { + if ! [[ $IS_MACOS ]]; then + return 0; + fi + + echo "Running installer 💻" + TOOLCHAIN=$(release_name).xctoolchain + xattr -dr com.apple.quarantine $(download_file pkg) + installer -pkg $(download_file pkg) -target CurrentUserHomeDirectory +} + +install_toolchain () { echo "Installing Swift toolchain 💻" - tar xzf $TOOLCHAIN_TAR - mv $TOOLCHAIN_PATH /usr/share/swift-toolchain - echo "Successfully installed Swift toolchain 🎉" -fi + if [ $IS_LINUX ]; then + tar xzf $(download_file tar.gz) + mkdir $(toolchains_path) + mv $(download_file) $(toolchain_path) + fi + + PATH=$(toolchain_path)/usr/bin:${PATH} + echo "PATH=$PATH" >> $GITHUB_ENV +} + +#-=============================================================================- +# Helpers +#-=============================================================================- + +# Example release URLs +# https://download.swift.org/swift-5.5.2-release/xcode/swift-5.5.2-RELEASE/swift-5.5.2-RELEASE-osx.pkg +# https://download.swift.org/swift-5.5.2-release/ubuntu1804/swift-5.5.2-RELEASE/swift-5.5.2-RELEASE-ubuntu18.04.tar.gz +# https://download.swift.org/swift-5.5.2-release/ubuntu2004/swift-5.5.2-RELEASE/swift-5.5.2-RELEASE-ubuntu20.04.tar.gz + +# Example development snapshot URLs +# https://download.swift.org/development/xcode/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a-osx.pkg +# https://download.swift.org/development/ubuntu1804/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a-ubuntu18.04.tar.gz +# https://download.swift.org/development/ubuntu1804/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a-ubuntu18.04.tar.gz.sig +# https://download.swift.org/development/ubuntu2004/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a-ubuntu20.04.tar.gz +# https://download.swift.org/development/ubuntu2004/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a/swift-DEVELOPMENT-SNAPSHOT-2022-01-09-a-ubuntu20.04.tar.gz.sig + +toolchain_path () { + if [ $IS_LINUX ]; then + echo $(toolchains_path)/$(release_name) + elif [ $IS_MACOS ]; then + echo $(toolchains_path)/$(release_name).xctoolchain + fi +} + +toolchains_path () { + if [ $IS_LINUX ]; then + echo /opt/swift-toolchains + elif [ $IS_MACOS ]; then + echo ${HOME}/Library/Developer/Toolchains + fi +} + +release_name () { + if [[ $SWIFT_VERSION == swift-DEVELOPMENT-SNAPSHOT* ]]; then + RELEASE_NAME=$SWIFT_VERSION + else + RELEASE_NAME=swift-$SWIFT_VERSION-RELEASE + fi + + echo $RELEASE_NAME +} + +download_file () { + FILETYPE=$1 + + if [ $IS_MACOS ]; then + ALT_PLATFORM=osx + elif [ $IS_LINUX ]; then + ALT_PLATFORM=ubuntu$UBUNTU_VERSION + fi + + RETURN_VALUE=$(release_name)-$ALT_PLATFORM + + if [ $FILETYPE ]; then + RETURN_VALUE=$RETURN_VALUE.$FILETYPE + fi + + echo $RETURN_VALUE +} + +download_url () { + DOWNLOAD_BASE_URL=https://download.swift.org + FILETYPE=$1 + + if [[ $SWIFT_VERSION == swift-DEVELOPMENT-SNAPSHOT* ]]; then + FOLDER=development + else + FOLDER=swift-$SWIFT_VERSION-release + fi + + if [ $IS_MACOS ]; then + PLATFORM=xcode + elif [ $IS_LINUX ]; then + PLATFORM=ubuntu${UBUNTU_VERSION//[.]/} + fi + + echo $DOWNLOAD_BASE_URL/$FOLDER/$PLATFORM/$(release_name)/$(download_file $FILETYPE) +} -export PATH=/usr/share/swift-toolchain/usr/bin:${PATH} -echo "PATH=$PATH" >> $GITHUB_ENV +install_swift