diff --git a/.github/workflows/build-chocolatey.yml b/.github/workflows/build-chocolatey.yml new file mode 100644 index 000000000000..9de87d8e5ad6 --- /dev/null +++ b/.github/workflows/build-chocolatey.yml @@ -0,0 +1,57 @@ +################################################################################################### +### THIS IS A REUSABLE WORKFLOW TO BUILD SCALA WITH CHOCOLATEY ### +### HOW TO USE: ### +### ### +### NOTE: ### +### ### +################################################################################################### + + +name: Build 'scala' Chocolatey Package +run-name: Build 'scala' (${{ inputs.version }}) Chocolatey Package + +on: + workflow_call: + inputs: + version: + required: true + type : string + url: + required: true + type : string + digest: + required: true + type : string + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: Replace the version placeholder + uses: richardrigutins/replace-in-files@v2 + with: + files: ./pkgs/chocolatey/scala.nuspec + search-text: '@LAUNCHER_VERSION@' + replacement-text: ${{ inputs.version }} + - name: Replace the URL placeholder + uses: richardrigutins/replace-in-files@v2 + with: + files: ./pkgs/chocolatey/tools/chocolateyInstall.ps1 + search-text: '@LAUNCHER_URL@' + replacement-text: ${{ inputs.url }} + - name: Replace the CHECKSUM placeholder + uses: richardrigutins/replace-in-files@v2 + with: + files: ./pkgs/chocolatey/tools/chocolateyInstall.ps1 + search-text: '@LAUNCHER_SHA256@' + replacement-text: ${{ inputs.digest }} + - name: Build the Chocolatey package (.nupkg) + run: choco pack ./pkgs/chocolatey/scala.nuspec --out ./pkgs/chocolatey + - name: Upload the Chocolatey package to GitHub + uses: actions/upload-artifact@v4 + with: + name: scala.nupkg + path: ./pkgs/chocolatey/scala.${{ inputs.version }}.nupkg + if-no-files-found: error + \ No newline at end of file diff --git a/.github/workflows/build-sdk.yml b/.github/workflows/build-sdk.yml new file mode 100644 index 000000000000..00ce04080534 --- /dev/null +++ b/.github/workflows/build-sdk.yml @@ -0,0 +1,58 @@ +################################################################################################### +### THIS IS A REUSABLE WORKFLOW TO BUILD THE SCALA LAUNCHERS ### +### HOW TO USE: ### +### - THSI WORKFLOW WILL PACKAGE THE ALL THE LAUNCHERS AND UPLOAD THEM TO GITHUB ARTIFACTS ### +### ### +### NOTE: ### +### - SEE THE WORFLOW FOR THE NAMES OF THE ARTIFACTS ### +################################################################################################### + + +name: Build Scala Launchers +run-name: Build Scala Launchers + +on: + workflow_call: + inputs: + java-version: + type : string + required : true + outputs: + universal-id: + description: ID of the `universal` package from GitHub Artifacts (Authentication Required) + value : ${{ jobs.build.outputs.universal-id }} + universal-digest: + description: The SHA256 of the uploaded artifact (universal) + value : ${{ jobs.build.outputs.universal-digest }} + + +jobs: + build: + runs-on: ubuntu-latest + outputs: + universal-id : ${{ steps.universal.outputs.artifact-id }} + universal-digest : ${{ steps.universal-digest.outputs.digest }} + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ inputs.java-version }} + cache : sbt + + - name: Build and pack the SDK (universal) + run : ./project/scripts/sbt dist/pack + + - name: Upload zip archive to GitHub Artifact (universal) + uses: actions/upload-artifact@v4 + id : universal + with: + path: ./dist/target/pack/* + name: scala3-universal + + - name: Compute SHA256 of the uploaded artifact (universal) + id : universal-digest + run : | + curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -o artifact.zip -L https://api.github.com/repos/scala/scala3/actions/artifacts/${{ steps.universal.outputs.artifact-id }}/zip + echo "digest=$(sha256sum artifact.zip | cut -d " " -f 1)" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 97c4a9d75277..196d7a34d899 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -756,3 +756,30 @@ jobs: WORKFLOW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} with: filename: .github/workflows/issue_nightly_failed.md + + build-sdk-package: + uses: ./.github/workflows/build-sdk.yml + if: + (github.event_name == 'pull_request' && !contains(github.event.pull_request.body, '[skip ci]')) || + (github.event_name == 'workflow_dispatch' && github.repository == 'scala/scala3') || + (github.event_name == 'schedule' && github.repository == 'scala/scala3') || + github.event_name == 'push' + with: + java-version: 8 + + build-chocolatey-package: + uses: ./.github/workflows/build-chocolatey.yml + needs: [ build-sdk-package ] + with: + version: 3.3.5-local # unused + url : https://api.github.com/repos/scala/scala3/actions/artifacts/${{ needs.build-sdk-package.outputs.universal-id }}/zip + digest : ${{ needs.build-sdk-package.outputs.universal-digest }} + + test-chocolatey-package: + uses: ./.github/workflows/test-chocolatey.yml + with: + version : 3.3.5-local # unused + java-version: 8 + if: github.event_name == 'pull_request' && contains(github.event.pull_request.body, '[test_chocolatey]') + needs: [ build-chocolatey-package ] + diff --git a/.github/workflows/publish-chocolatey.yml b/.github/workflows/publish-chocolatey.yml new file mode 100644 index 000000000000..3b31728a50ba --- /dev/null +++ b/.github/workflows/publish-chocolatey.yml @@ -0,0 +1,39 @@ +################################################################################################### +### THIS IS A REUSABLE WORKFLOW TO PUBLISH SCALA TO CHOCOLATEY ### +### HOW TO USE: ### +### - THE RELEASE WORKFLOW SHOULD CALL THIS WORKFLOW ### +### - IT WILL PUBLISH TO CHOCOLATEY THE MSI ### +### ### +### NOTE: ### +### - WE SHOULD KEEP IN SYNC THE NAME OF THE MSI WITH THE ACTUAL BUILD ### +### - WE SHOULD KEEP IN SYNC THE URL OF THE RELEASE ### +### - IT ASSUMES THAT THE `build-chocolatey` WORKFLOW WAS EXECUTED BEFORE ### +################################################################################################### + + +name: Publish Scala to Chocolatey +run-name: Publish Scala ${{ inputs.version }} to Chocolatey + +on: + workflow_call: + inputs: + version: + required: true + type: string + secrets: + # Connect to https://community.chocolatey.org/profiles/scala + # Accessible via https://community.chocolatey.org/account + API-KEY: + required: true + +jobs: + publish: + runs-on: windows-latest + steps: + - name: Fetch the Chocolatey package from GitHub + uses: actions/download-artifact@v4 + with: + name: scala.nupkg + - name: Publish the package to Chocolatey + run: choco push scala.nupkg --source https://push.chocolatey.org/ --api-key ${{ secrets.API-KEY }} + \ No newline at end of file diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index fa65f8cd5ae6..03ff19444d2f 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -1,4 +1,17 @@ -name: Releases +################################################################################################### +### OFFICIAL RELEASE WORKFLOW ### +### HOW TO USE: ### +### - THIS WORKFLOW WILL NEED TO BE TRIGGERED MANUALLY ### +### ### +### NOTE: ### +### - THIS WORKFLOW SHOULD ONLY BE RUN ON STABLE RELEASES ### +### - IT ASSUMES THAT THE PRE-RELEASE WORKFLOW WAS PREVIOUSLY EXECUTED ### +### ### +################################################################################################### + +name: Official release of Scala +run-name: Official release of Scala ${{ inputs.version }} + on: workflow_dispatch: inputs: @@ -11,7 +24,7 @@ permissions: contents: read jobs: - publish_release: + publish-sdkman: runs-on: [self-hosted, Linux] container: image: lampepfl/dotty:2021-03-22 @@ -35,3 +48,35 @@ jobs: - name: Publish to SDKMAN run: .github/workflows/scripts/publish-sdkman.sh ${{ inputs.version }} + + compute-digest: + runs-on: ubuntu-latest + outputs: + digest: ${{ steps.digest.outputs.digest }} + steps: + - name: Compute the SHA256 of scala3-${{ inputs.version }}.zip in GitHub Release + id: digest + run: | + curl -o artifact.zip -L https://github.com/scala/scala3/releases/download/${{ inputs.version }}/scala3-${{ inputs.version }}.zip + echo "digest=$(sha256sum artifact.zip | cut -d " " -f 1)" >> "$GITHUB_OUTPUT" + + build-chocolatey: + uses: ./.github/workflows/build-chocolatey.yml + needs: compute-digest + with: + version: ${{ inputs.version }} + url : 'https://github.com/scala/scala3/releases/download/${{ inputs.version }}/scala3-${{ inputs.version }}.zip' + digest : ${{ needs.compute-digest.outputs.digest }} + test-chocolatey: + uses: ./.github/workflows/test-chocolatey.yml + needs: build-chocolatey + with: + version : ${{ inputs.version }} + java-version: 8 + publish-chocolatey: + uses: ./.github/workflows/publish-chocolatey.yml + needs: [ build-chocolatey, test-chocolatey ] + with: + version: ${{ inputs.version }} + secrets: + API-KEY: ${{ secrets.CHOCOLATEY_KEY }} diff --git a/.github/workflows/test-chocolatey.yml b/.github/workflows/test-chocolatey.yml new file mode 100644 index 000000000000..b6ca9bf74b12 --- /dev/null +++ b/.github/workflows/test-chocolatey.yml @@ -0,0 +1,51 @@ +################################################################################################### +### THIS IS A REUSABLE WORKFLOW TO TEST SCALA WITH CHOCOLATEY ### +### HOW TO USE: ### +### ### +### NOTE: ### +### ### +################################################################################################### + +name: Test 'scala' Chocolatey Package +run-name: Test 'scala' (${{ inputs.version }}) Chocolatey Package + +on: + workflow_call: + inputs: + version: + required: true + type: string + java-version: + required: true + type : string + +env: + CHOCOLATEY-REPOSITORY: chocolatey-pkgs + DOTTY_CI_INSTALLATION: ${{ secrets.GITHUB_TOKEN }} + +jobs: + test: + runs-on: windows-latest + steps: + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ inputs.java-version }} + - name: Download the 'nupkg' from GitHub Artifacts + uses: actions/download-artifact@v4 + with: + name: scala.nupkg + path: ${{ env.CHOCOLATEY-REPOSITORY }} + - name : Install the `scala` package with Chocolatey + run : choco install scala --source "${{ env.CHOCOLATEY-REPOSITORY }}" --pre # --pre since we might be testing non-stable releases + shell: pwsh + - name : Test the `scala` command + run : scala --version + shell: pwsh + - name : Test the `scalac` command + run : scalac --version + - name : Test the `scaladoc` command + run : scaladoc --version + - name : Uninstall the `scala` package + run : choco uninstall scala + \ No newline at end of file diff --git a/pkgs/chocolatey/README.md b/pkgs/chocolatey/README.md new file mode 100644 index 000000000000..c8af9cf92666 --- /dev/null +++ b/pkgs/chocolatey/README.md @@ -0,0 +1,17 @@ +

Configuration for Chocolatey

+ +Official support for Chocolatey started by the release of Scala 3.6.0 and was backported (with modifications) to the Scala 3.3.5 LTS. +Scala 3.3 LTS Chocolatey package uses universal package (.jar) instead of native runners. + +> [!IMPORTANT] +> This folder contains the templates to generate the configuration for Chocolatey. +> The `scala.nuspec` and `chocolateyInstall.ps1` files needs to be rewritten by changing the following placeholders: +> - @LAUNCHER_VERSION@ : Placeholder for the current scala version to deploy +> - @LAUNCHER_URL@ : Placeholder for the URL to the windows zip released on GitHub +> - @LAUNCHER_SHA256@ : Placeholder for the SHA256 of the msi file released on GitHub + +## Important information + +- How to create a *Chocolatey* package: https://docs.chocolatey.org/en-us/create/create-packages/ +- Guidelines to follow for the package icon: https://docs.chocolatey.org/en-us/create/create-packages/#package-icon-guidelines +- `.nuspec` format specification: https://learn.microsoft.com/en-gb/nuget/reference/nuspec diff --git a/pkgs/chocolatey/icon.svg b/pkgs/chocolatey/icon.svg new file mode 100644 index 000000000000..0ccb404b5624 --- /dev/null +++ b/pkgs/chocolatey/icon.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pkgs/chocolatey/scala.nuspec b/pkgs/chocolatey/scala.nuspec new file mode 100644 index 000000000000..bb2e0e07ce70 --- /dev/null +++ b/pkgs/chocolatey/scala.nuspec @@ -0,0 +1,25 @@ + + + + scala + @LAUNCHER_VERSION@ + Scala + scala + scala + scala + Scala + Official release of the Scala Programming Language on Chocolatey. + https://github.com/scala/scala3/tree/main/pkgs/chocolatey + https://github.com/scala/scala3 + https://scala-lang.org/ + https://github.com/scala/scala3/issues + © 2002-2024, LAMP/EPFL + https://cdn.jsdelivr.net/gh/scala/scala3@a046b0014ffd9536144d67a48f8759901b96d12f/pkgs/chocolatey/icon.svg + https://github.com/scala/scala3/blob/main/LICENSE + true + https://github.com/scala/scala3/releases + + + + + diff --git a/pkgs/chocolatey/tools/chocolateyInstall.ps1 b/pkgs/chocolatey/tools/chocolateyInstall.ps1 new file mode 100644 index 000000000000..3117efadaf0e --- /dev/null +++ b/pkgs/chocolatey/tools/chocolateyInstall.ps1 @@ -0,0 +1,46 @@ +$ErrorActionPreference = 'Stop'; + +$unzipLocation = Split-Path -Parent $MyInvocation.MyCommand.Definition # Get the root of chocolatey folder +$unzipLocation = Join-Path $unzipLocation "$($env:chocolateyPackageName)" # Append the package's name +$unzipLocation = Join-Path $unzipLocation "$($env:chocolateyPackageVersion)" # Append the package's version + +# Configure the installation arguments +$packageArgs = @{ + packageName = 'scala' + Url64 = '@LAUNCHER_URL@' + UnzipLocation = $unzipLocation + Checksum64 = '@LAUNCHER_SHA256@' + ChecksumType64 = 'SHA256' +} + +## In case we are running in the CI, add the authorisation header to fetch the zip +## See: https://docs.github.com/en/rest/actions/artifacts?apiVersion=2022-11-28#download-an-artifact +if ($env:DOTTY_CI_INSTALLATION) { + Write-Host "Installing the Chocolatey package in Scala 3's CI" + $packageArgs += @{ + Options = @{ + Headers = @{ + Accept = 'application/vnd.github+json' + Authorization = "Bearer $env:DOTTY_CI_INSTALLATION" + } + } + } +} + +Install-ChocolateyZipPackage @packageArgs + +# Find the path to the bin directory to create the shims +if($env:DOTTY_CI_INSTALLATION) { + $scalaBinPath = Join-Path $unzipLocation 'bin' # Update this path if the structure inside the ZIP changes +} else { + $extractedDir = Get-ChildItem -Path $unzipLocation | Where-Object { $_.PSIsContainer } | Select-Object -First 1 + $scalaBinPath = Join-Path $unzipLocation $extractedDir | Join-Path -ChildPath 'bin' +} + +# Iterate through the .bat files in the bin directory and create shims +Write-Host "Creating shims for .bat file from $scalaBinPath" +Get-ChildItem -Path $scalaBinPath -Filter '*.bat' | ForEach-Object { + $file = $_.FullName + Write-Host "Creating shim for $file..." + Install-BinFile -Name $_.BaseName -Path $file +} diff --git a/pkgs/chocolatey/tools/chocolateyUninstall.ps1 b/pkgs/chocolatey/tools/chocolateyUninstall.ps1 new file mode 100644 index 000000000000..387914af5d09 --- /dev/null +++ b/pkgs/chocolatey/tools/chocolateyUninstall.ps1 @@ -0,0 +1,21 @@ +$ErrorActionPreference = 'Stop'; + +$unzipLocation = Split-Path -Parent $MyInvocation.MyCommand.Definition # Get the root of chocolatey folder +$unzipLocation = Join-Path $unzipLocation "$($env:chocolateyPackageName)" # Append the package's name +$unzipLocation = Join-Path $unzipLocation "$($env:chocolateyPackageVersion)" # Append the package's version + +# Find the path to the bin directory to create the shims +if($env:DOTTY_CI_INSTALLATION) { + $scalaBinPath = Join-Path $unzipLocation 'bin' # Update this path if the structure inside the ZIP changes + } else { + $extractedDir = Get-ChildItem -Path $unzipLocation | Where-Object { $_.PSIsContainer } | Select-Object -First 1 + $scalaBinPath = Join-Path $unzipLocation $extractedDir | Join-Path -ChildPath 'bin' + } + +# Iterate through the .bat files in the bin directory and remove shims +Write-Host "Removing shims for .bat file from $scalaBinPath" +Get-ChildItem -Path $scalaBinPath -Filter '*.bat' | ForEach-Object { + $file = $_.FullName + Write-Host "Removing shim for $file..." + Uninstall-BinFile -Name $_.BaseName -Path $file +}