From 15fff0c3d23870a707e0622e8e264c0d5723d78e Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Mon, 10 Nov 2025 13:55:33 -0500 Subject: [PATCH 1/5] Add param to cache downloaded toolchains on Windows --- action.yml | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index abae6e1..dd2cca6 100644 --- a/action.yml +++ b/action.yml @@ -55,6 +55,11 @@ inputs: required: false default: 'false' type: boolean + cache: + description: 'Cache downloaded toolchains (Windows only)' + required: false + default: 'false' + type: boolean runs: using: 'composite' @@ -119,16 +124,48 @@ runs: Write-Output "RESOLVED_SWIFT_VERSION=$SwiftVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append Write-Output "RESOLVED_SWIFT_BUILD=$SwiftBuild" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append shell: pwsh - - name: Fetch installer from GitHub release - if: inputs.source == 'custom' + + - name: Generate cache key + if: runner.os == 'Windows' && inputs.cache == 'true' + id: cache-key + run: | + if ("${{ inputs.source }}" -eq "swift.org") { + $CacheKey = "swift-toolchain-windows-${{ inputs.build_arch }}-${env:RESOLVED_SWIFT_VERSION}-${env:RESOLVED_SWIFT_BUILD}" + } else { + $CacheKey = "swift-toolchain-windows-custom-${{ inputs.github-repo }}-${{ inputs.release-tag-name }}-${{ inputs.release-asset-name }}".Replace("/", "-") + } + Write-Output "key=$CacheKey" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append + + $CachePath = [IO.Path]::Combine(${env:Temp}, "installer.exe") + Write-Output "path=$CachePath" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append + shell: pwsh + + - name: Restore cached toolchain + if: runner.os == 'Windows' && inputs.cache == 'true' + id: cache-restore + uses: actions/cache/restore@v4 + with: + path: ${{ steps.cache-key.outputs.path }} + key: ${{ steps.cache-key.outputs.key }} + + - name: Fetch installer from GitHub release (Windows) + if: runner.os == 'Windows' && inputs.source == 'custom' && (inputs.cache != 'true' || steps.cache-restore.outputs.cache-hit != 'true') env: GH_TOKEN: ${{ inputs.github-token }} run: | gh release download "${{ inputs.release-tag-name }}" --skip-existing --repo "${{ inputs.github-repo }}" --pattern "${{ inputs.release-asset-name }}" --output $([IO.Path]::Combine(${env:Temp}, "installer.exe")) shell: pwsh + - name: Fetch installer from GitHub release (Linux/macOS) + if: runner.os != 'Windows' && inputs.source == 'custom' + env: + GH_TOKEN: ${{ inputs.github-token }} + run: | + gh release download "${{ inputs.release-tag-name }}" --skip-existing --repo "${{ inputs.github-repo }}" --pattern "${{ inputs.release-asset-name }}" + shell: bash + - name: Fetch installer from swift.org - if: runner.os == 'Windows' && inputs.source == 'swift.org' + if: runner.os == 'Windows' && inputs.source == 'swift.org' && (inputs.cache != 'true' || steps.cache-restore.outputs.cache-hit != 'true') run: | # Download the appropriate installer $URL = if ("${{ inputs.build_arch }}" -eq "amd64") { @@ -147,6 +184,13 @@ runs: } shell: pwsh + - name: Save toolchain to cache + if: runner.os == 'Windows' && inputs.cache == 'true' && steps.cache-restore.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: ${{ steps.cache-key.outputs.path }} + key: ${{ steps.cache-key.outputs.key }} + - name: Install Swift id: install-swift if: runner.os == 'Windows' From 4e9309b03ee0fc433323c786a56837c215767e66 Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Mon, 10 Nov 2025 14:39:34 -0500 Subject: [PATCH 2/5] Pipe strings directly --- action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index dd2cca6..05fffa3 100644 --- a/action.yml +++ b/action.yml @@ -134,10 +134,10 @@ runs: } else { $CacheKey = "swift-toolchain-windows-custom-${{ inputs.github-repo }}-${{ inputs.release-tag-name }}-${{ inputs.release-asset-name }}".Replace("/", "-") } - Write-Output "key=$CacheKey" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append + "key=$CacheKey" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append $CachePath = [IO.Path]::Combine(${env:Temp}, "installer.exe") - Write-Output "path=$CachePath" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append + "path=$CachePath" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append shell: pwsh - name: Restore cached toolchain From 1d0eb404b2f2b2e88f1d074c759a3a57be7462ad Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Mon, 10 Nov 2025 16:27:01 -0500 Subject: [PATCH 3/5] Cross platform --- action.yml | 82 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/action.yml b/action.yml index 05fffa3..59682a1 100644 --- a/action.yml +++ b/action.yml @@ -125,7 +125,7 @@ runs: Write-Output "RESOLVED_SWIFT_BUILD=$SwiftBuild" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append shell: pwsh - - name: Generate cache key + - name: Generate cache key (Windows) if: runner.os == 'Windows' && inputs.cache == 'true' id: cache-key run: | @@ -140,13 +140,36 @@ runs: "path=$CachePath" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append shell: pwsh + - name: Generate cache key (Linux/macOS) + if: runner.os != 'Windows' && inputs.cache == 'true' + id: cache-key-posix + run: | + OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]') + + if [[ "${{ inputs.source }}" == "swift.org" ]]; then + CACHE_KEY="swift-toolchain-${OS}-${{ inputs.build_arch }}-${RESOLVED_SWIFT_VERSION}-${RESOLVED_SWIFT_BUILD}" + else + CACHE_KEY="swift-toolchain-${OS}-custom-${{ inputs.github-repo }}-${{ inputs.release-tag-name }}-${{ inputs.release-asset-name }}" + CACHE_KEY="${CACHE_KEY//\//-}" + fi + echo "key=${CACHE_KEY}" >> $GITHUB_OUTPUT + + # Set cache path based on OS + if [[ "${{ runner.os }}" == "Linux" ]]; then + CACHE_PATH="swift-toolchain.tar.gz" + else + CACHE_PATH="swift-${RESOLVED_SWIFT_BUILD}-osx.pkg" + fi + echo "path=${CACHE_PATH}" >> $GITHUB_OUTPUT + shell: bash + - name: Restore cached toolchain - if: runner.os == 'Windows' && inputs.cache == 'true' + if: inputs.cache == 'true' id: cache-restore uses: actions/cache/restore@v4 with: - path: ${{ steps.cache-key.outputs.path }} - key: ${{ steps.cache-key.outputs.key }} + path: ${{ runner.os == 'Windows' && steps.cache-key.outputs.path || steps.cache-key-posix.outputs.path }} + key: ${{ runner.os == 'Windows' && steps.cache-key.outputs.key || steps.cache-key-posix.outputs.key }} - name: Fetch installer from GitHub release (Windows) if: runner.os == 'Windows' && inputs.source == 'custom' && (inputs.cache != 'true' || steps.cache-restore.outputs.cache-hit != 'true') @@ -157,11 +180,17 @@ runs: shell: pwsh - name: Fetch installer from GitHub release (Linux/macOS) - if: runner.os != 'Windows' && inputs.source == 'custom' + if: runner.os != 'Windows' && inputs.source == 'custom' && (inputs.cache != 'true' || steps.cache-restore.outputs.cache-hit != 'true') env: GH_TOKEN: ${{ inputs.github-token }} run: | gh release download "${{ inputs.release-tag-name }}" --skip-existing --repo "${{ inputs.github-repo }}" --pattern "${{ inputs.release-asset-name }}" + + if [[ "${{ runner.os }}" == "Linux" ]]; then + mv "${{ inputs.release-asset-name }}" swift-toolchain.tar.gz + else + mv "${{ inputs.release-asset-name }}" swift-${RESOLVED_SWIFT_BUILD}-osx.pkg + fi shell: bash - name: Fetch installer from swift.org @@ -184,12 +213,39 @@ runs: } shell: pwsh + - name: Fetch installer from swift.org (Linux) + if: runner.os == 'Linux' && inputs.source == 'swift.org' && (inputs.cache != 'true' || steps.cache-restore.outputs.cache-hit != 'true') + run: | + source /etc/os-release + case ${ID} in + ubuntu) + case ${VERSION_ID} in + 16.04|18.04|20.04|22.04|24.04) + curl -sL https://download.swift.org/${RESOLVED_SWIFT_VERSION}/ubuntu${VERSION_ID/./}/swift-${RESOLVED_SWIFT_BUILD}/swift-${RESOLVED_SWIFT_BUILD}-ubuntu${VERSION_ID}.tar.gz -o swift-toolchain.tar.gz + ;; + *) + echo "::error file=/etc/os-release,title=Unsupported::unsupported ${ID} release (${VERSION_ID})" + exit 1 + esac + ;; + *) + echo ::error unknown Linux distribution + exit 1 + esac + shell: bash + + - name: Fetch installer from swift.org (macOS) + if: runner.os == 'macOS' && inputs.source == 'swift.org' && (inputs.cache != 'true' || steps.cache-restore.outputs.cache-hit != 'true') + run: | + curl -sOL https://download.swift.org/${RESOLVED_SWIFT_VERSION}/xcode/swift-${RESOLVED_SWIFT_BUILD}/swift-${RESOLVED_SWIFT_BUILD}-osx.pkg + shell: bash + - name: Save toolchain to cache - if: runner.os == 'Windows' && inputs.cache == 'true' && steps.cache-restore.outputs.cache-hit != 'true' + if: inputs.cache == 'true' && steps.cache-restore.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: - path: ${{ steps.cache-key.outputs.path }} - key: ${{ steps.cache-key.outputs.key }} + path: ${{ runner.os == 'Windows' && steps.cache-key.outputs.path || steps.cache-key-posix.outputs.path }} + key: ${{ runner.os == 'Windows' && steps.cache-key.outputs.key || steps.cache-key-posix.outputs.key }} - name: Install Swift id: install-swift @@ -334,11 +390,6 @@ runs: ubuntu) case ${VERSION_ID} in 16.04|18.04|20.04|22.04|24.04) - if [[ "${{ inputs.source }}" == "custom" ]]; then - mv "${{ inputs.release-asset-name }}" swift-toolchain.tar.gz - else - curl -sL https://download.swift.org/${RESOLVED_SWIFT_VERSION}/ubuntu${VERSION_ID/./}/swift-${RESOLVED_SWIFT_BUILD}/swift-${RESOLVED_SWIFT_BUILD}-ubuntu${VERSION_ID}.tar.gz -o swift-toolchain.tar.gz - fi tar zxf swift-toolchain.tar.gz -C ${HOME} rm -f swift-toolchain.tar.gz ;; @@ -358,11 +409,6 @@ runs: - name: Install Swift if: runner.os == 'macOS' run: | - if [[ "${{ inputs.source }}" == "custom" ]]; then - mv "${{ inputs.release-asset-name }}" swift-${RESOLVED_SWIFT_BUILD}-osx.pkg - else - curl -sOL https://download.swift.org/${RESOLVED_SWIFT_VERSION}/xcode/swift-${RESOLVED_SWIFT_BUILD}/swift-${RESOLVED_SWIFT_BUILD}-osx.pkg - fi xattr -dr com.apple.quarantine swift-${RESOLVED_SWIFT_BUILD}-osx.pkg installer -pkg swift-${RESOLVED_SWIFT_BUILD}-osx.pkg -target CurrentUserHomeDirectory rm -f swift-${RESOLVED_SWIFT_BUILD}-osx.pkg From 314ae1bb389e56148df8f3f3abd330d6216c17bc Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Mon, 10 Nov 2025 16:58:45 -0500 Subject: [PATCH 4/5] Update param description --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 59682a1..50529f5 100644 --- a/action.yml +++ b/action.yml @@ -56,7 +56,7 @@ inputs: default: 'false' type: boolean cache: - description: 'Cache downloaded toolchains (Windows only)' + description: 'Cache downloaded toolchains' required: false default: 'false' type: boolean From 83817e3d18217baa0d907ff7e65fb6d92f39f11e Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Mon, 10 Nov 2025 17:09:26 -0500 Subject: [PATCH 5/5] Dedupe Linux version check --- action.yml | 58 ++++++++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/action.yml b/action.yml index 50529f5..cdc6e70 100644 --- a/action.yml +++ b/action.yml @@ -125,6 +125,27 @@ runs: Write-Output "RESOLVED_SWIFT_BUILD=$SwiftBuild" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append shell: pwsh + - name: Validate Linux distribution + if: runner.os == 'Linux' + run: | + source /etc/os-release + echo ${ID} ${VERSION_ID} + case ${ID} in + ubuntu) + case ${VERSION_ID} in + 16.04|18.04|20.04|22.04|24.04) + ;; + *) + echo "::error file=/etc/os-release,title=Unsupported::unsupported ${ID} release (${VERSION_ID})" + exit 1 + esac + ;; + *) + echo ::error unknown Linux distribution + exit 1 + esac + shell: bash + - name: Generate cache key (Windows) if: runner.os == 'Windows' && inputs.cache == 'true' id: cache-key @@ -217,21 +238,7 @@ runs: if: runner.os == 'Linux' && inputs.source == 'swift.org' && (inputs.cache != 'true' || steps.cache-restore.outputs.cache-hit != 'true') run: | source /etc/os-release - case ${ID} in - ubuntu) - case ${VERSION_ID} in - 16.04|18.04|20.04|22.04|24.04) - curl -sL https://download.swift.org/${RESOLVED_SWIFT_VERSION}/ubuntu${VERSION_ID/./}/swift-${RESOLVED_SWIFT_BUILD}/swift-${RESOLVED_SWIFT_BUILD}-ubuntu${VERSION_ID}.tar.gz -o swift-toolchain.tar.gz - ;; - *) - echo "::error file=/etc/os-release,title=Unsupported::unsupported ${ID} release (${VERSION_ID})" - exit 1 - esac - ;; - *) - echo ::error unknown Linux distribution - exit 1 - esac + curl -sL https://download.swift.org/${RESOLVED_SWIFT_VERSION}/ubuntu${VERSION_ID/./}/swift-${RESOLVED_SWIFT_BUILD}/swift-${RESOLVED_SWIFT_BUILD}-ubuntu${VERSION_ID}.tar.gz -o swift-toolchain.tar.gz shell: bash - name: Fetch installer from swift.org (macOS) @@ -384,25 +391,8 @@ runs: - name: Install Swift if: runner.os == 'Linux' run: | - source /etc/os-release - echo ${ID} ${VERSION_ID} - case ${ID} in - ubuntu) - case ${VERSION_ID} in - 16.04|18.04|20.04|22.04|24.04) - tar zxf swift-toolchain.tar.gz -C ${HOME} - rm -f swift-toolchain.tar.gz - ;; - *) - echo "::error file=/etc/os-release,title=Unsupported::unsupported ${ID} release (${VERSION_ID})" - exit 1 - esac - ;; - *) - echo ::error unknown Linux distribution - exit 1 - esac - + tar zxf swift-toolchain.tar.gz -C ${HOME} + rm -f swift-toolchain.tar.gz echo "${HOME}/usr/bin" >> $GITHUB_PATH shell: bash