├── .github └── workflows │ └── cla.yml ├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── LICENSE ├── NOTICE ├── README.md ├── admin ├── build.ps1 ├── build.sh └── files │ ├── jenkins_lightbend_chara.enc │ └── ssh_config ├── appveyor.yml ├── build.sbt ├── project ├── Docs.scala ├── ScalaDist.scala ├── Unix.scala ├── Versioning.scala ├── Wix.scala ├── build.properties └── plugins.sbt ├── scripts ├── common ├── common.ps1 └── jobs │ └── release │ └── website │ ├── archives │ └── update-api └── src ├── debian └── changelog └── linux └── copyright /.github/workflows/cla.yml: -------------------------------------------------------------------------------- 1 | name: "Check Scala CLA" 2 | on: 3 | pull_request: 4 | jobs: 5 | cla-check: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Verify CLA 9 | uses: scala/cla-checker@v1 10 | with: 11 | author: ${{ github.event.pull_request.user.login }} 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # The scala/scala travis job triggers a build of scala/scala-dist with `mode=release`. For 2 | # the other modes (see below), use the web UI to trigger a build. 3 | # 4 | # Additional env vars are defined using a `before_install` custom config(*), for example 5 | # before_install: export version=2.12.N scala_sha=abc123 mode=release 6 | # 7 | # Available modes: 8 | # - `release` to build native packages and upload them to S3 9 | # - `archives` to copy archives to chara (for scala-lang.org) 10 | # - `update-api` to update the scaladoc api symlinks 11 | # 12 | # (*) Using an `env: global: ...` section does not work because that overrides the default `env` 13 | # from .travis.yml. For releases triggered with the REST API we could use the "merge mode", but 14 | # not when triggering from the web UI. Anyway, `before_install` works well. 15 | 16 | # we need rpmbuild but it's unlikely to be whitelisted, according to 17 | # https://github.com/travis-ci/apt-package-whitelist/pull/1700 18 | sudo: required 19 | dist: xenial 20 | install: 21 | - sudo apt-get -qq update 22 | - sudo apt-get install -y rpm 23 | 24 | language: scala 25 | # java 11+ needed for sttp 26 | jdk: openjdk21 27 | 28 | env: 29 | global: 30 | # PRIV_KEY_SECRET 31 | - secure: "NlnFqZs4mvCi63GqCdUNDsx9BoiyrjgoV0cUaKlhVYp49/qAMlEaKf6JABWy/oCHoWsTyysyLEtZLsWfjAyE4+FUHSzngNUHVFBbtyudA6aKQ7jMsqkcMM/K0h+ymnhHSv8bugc8jXKFgmfYk4YTi5dZgv8CAOSQFAFUaxVdYTY=" 32 | # APPVEYOR_TOKEN (login with GitHub as lrytz, use the scala organization) 33 | - secure: "aHM0UWkbFN0bXQja2f9lUcSgqHzXYkYqqV8/nP5MTLKJG8BpuaLYxI4gHfkPmxSm9/TTniA3zUVN//lJTvhco5J5Dtxfo5DeCLWsjQcQxrsgAFD97FpMpGbtFAViZuiv7SdPGvzXQY6AwvteBpxOday4T224aH5OjZJ0DxySx8Q=" 34 | # TRAVIS_TOKEN (login with GitHub as SethTisue) 35 | - secure: "KzcB0qrsnD0o4iBW2dI/5uoHoPF8EVJpC+T+caA76WaXKRqVwr996FM83ky7XDeUjwop2bBtoIIiWXoTFqCI/oyIYggcdhphmdnq9IKGG3LXD49QUq60MRSRc+jAg3RY0TPQ/f4qcZaLfa0PHGN79n1DbYlSeZfwSg+xKlZ2f/8=" 36 | # AWS_ACCESS_KEY_ID 37 | - secure: "BrsLFLXLdJ3aesJGuoVXFdKluYl7QYBYjn5+ttoep2nc6/E+L3UDaR//ztxwex4a9yFi5q2jCs911FzVsk78ODamr5w8FBlOuu06RoVx642+U/agG7yUdAtvEzH2KVTBNjY0oYHZ+OlVEkeYgnkrsbfki+ujPWEnxkakWyrGtJw=" 38 | # AWS_SECRET_ACCESS_KEY 39 | - secure: "dv0pR9uqnLyKVHu1L1nvl5TVpo3bOxh4icLNybwFyCFQd9XiM/RU8Vhx3svZqqnAG+GiCDSiCaBQkTLUS5u9e+9eVw3cUj5meNr9EW673f8D6H8Tr433jlvu54CynD9DsBjhNo/xIrECOKTq+0wu480OLSjOkuNoclG2dSm4Dis=" 40 | # GITHUB_OAUTH_TOKEN (for GitHub user scala-jenkins, same token as scabot) 41 | - secure: "KetupmuH5L7nJjouavdPpvuc7imL9T01zI/OdTYhzOmuTSHV8tP6TVykRcVl73ZBkEre+Es7TYw46HjlhTqGtj//6V+8XCNZ4hIt1IYEA2v+IBmIBCtuVnZdlY09/DqM8vxZjhnLFhjQlTvkCZdzc1lfzN1AVtceUvKqJpnzGS0=" 42 | script: 43 | - source scripts/common 44 | - postCommitStatus "pending" 45 | - admin/build.sh 46 | 47 | after_script: 48 | - | 49 | if [[ "$TRAVIS_TEST_RESULT" == "0" ]]; then 50 | local state="success" 51 | else 52 | local state="failure" 53 | fi 54 | postCommitStatus $state 55 | 56 | cache: 57 | directories: 58 | - $HOME/.ivy2 59 | - $HOME/.sbt/boot 60 | - $HOME/.sbt/launchers 61 | before_cache: 62 | - find $HOME/.sbt -name "*.lock" | xargs rm 63 | - find $HOME/.ivy2 -name "ivydata-*.properties" | xargs rm 64 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | all repositories in these organizations: 2 | 3 | * [scala](https://github.com/scala) 4 | * [scalacenter](https://github.com/scalacenter) 5 | * [lampepfl](https://github.com/lampepfl) 6 | 7 | are covered by the Scala Code of Conduct: https://scala-lang.org/conduct/ 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Scala 2 | Copyright (c) 2002-2025 EPFL 3 | Copyright (c) 2011-2025 Lightbend, Inc. dba Akka 4 | 5 | Scala includes software developed at 6 | LAMP/EPFL (https://lamp.epfl.ch/) and 7 | Akka (https://akka.io/). 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"). 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | This software includes projects with other licenses -- see `doc/LICENSE.md`. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scala 2.13 Distribution 2 | 3 | This project morphs the `"org.scala-lang" % "scala-dist" % $version` maven artifact 4 | into a Scala `$version` distribution (zip, tar.gz, deb, rpm, and msi). 5 | 6 | To build a distribution, run: 7 | 8 | * `Universal/packageBin` - Builds the universal zip installer 9 | * `UniversalDocs/packageBin` - Builds the universal documentation zip 10 | * `Debian/packageBin` - Builds the Debian DEB file. *requires dpkg-deb* 11 | * `Rpm/packageBin` - Builds the yum RPM file. *requires rpmbuild* 12 | * `Windows/packageBin` - Builds the Windows MSI. *requires WiX 3.6* 13 | 14 | Alternatively, the `s3Upload` task's mappings are configured based on the platform 15 | the installer is running on. On Windows, it builds the MSI; on another platform, 16 | it'll create and upload the other packages in the above list. (Use `s3Upload/mappings` for a dry-run.) 17 | 18 | The version of Scala to package is derived from the most recent git tag, 19 | or you can specify it using `-Dproject.version`. 20 | 21 | ## Windows VM 22 | 23 | - install Windows 7 professional N 64-bit, ensure network access to GitHub 24 | - install Oracle Java 6 JDK 25 | - install WiX v3.6 (reboot!) 26 | - download sbt launcher from xsbt.org to `c:\users\jenkins\Downloads` 27 | - install Git 28 | - configure the Jenkins master's tool locations for 29 | - HOME 30 | - JDK path 31 | - Git (path of git.exe) 32 | - sbt launch jar 33 | 34 | ## Contributing 35 | 36 | Please sign the [CLA](https://contribute.akka.io/contribute/cla/scala). 37 | 38 | The branching structure mimics that of [scala/scala](https://github.com/scala/scala); 39 | there are branches for 2.12.x and 2.13.x. 40 | -------------------------------------------------------------------------------- /admin/build.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | Function checkExit() { 4 | if (-not $?) { 5 | echo "Last command failed." 6 | Exit 1 7 | } 8 | } 9 | 10 | Function ensureVersion() { 11 | $verPat="^[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)?$" 12 | if ($env:version -notmatch $verPat) { 13 | echo "Not a valid Scala version: '$env:version'" 14 | Exit 1 15 | } 16 | } 17 | 18 | Function clearIvyCache() { 19 | remove-item -erroraction ignore -force -verbose $homeDir\.ivy2\exclude_classifiers, $homeDir\.ivy2\exclude_classifiers.lock 20 | remove-item -erroraction ignore -force -verbose -recurse $homeDir\.ivy2\cache\org.scala-lang, $homeDir\.ivy2\cache\org.scala-lang.modules 21 | remove-item -erroraction ignore -force -verbose -recurse $homeDir\.ivy2\local\org.scala-lang, $homeDir\.ivy2\local\org.scala-lang.modules 22 | get-childitem -erroraction ignore -path $homeDir\.ivy2 -recurse -include "*compiler-interface*$env:version*" | remove-item -force -recurse -verbose 23 | get-childitem -erroraction ignore -path $homeDir\.sbt -recurse -include "*compiler-interface*$env:version*" | remove-item -force -recurse -verbose 24 | } 25 | 26 | # oh boy. i don't (want to) fully understand, but executing commands and redirecting is difficult. 27 | # - https://mnaoumov.wordpress.com/2015/01/11/execution-of-external-commands-in-powershell-done-right/ 28 | # - https://stackoverflow.com/a/35980675/248998 29 | # letting cmd do the redirect avoids confusing powershell. 30 | & cmd /c 'java -version' '2>&1' 31 | checkExit 32 | 33 | if ($env:APPVEYOR_FORCED_BUILD -eq 'true') { 34 | ensureVersion 35 | clearIvyCache 36 | if ($env:mode -eq 'release') { 37 | if ($env:version -match '-bin-' -or $env:version -match '-pre-') { 38 | & cmd /c "sbt ""-Dproject.version=$env:version"" clean update ""show s3Upload/mappings""" '2>&1' 39 | } else { 40 | echo "Running a release for $env:version" 41 | & cmd /c "sbt ""-Dproject.version=$env:version"" clean update ghUpload" '2>&1' 42 | } 43 | checkExit 44 | } else { 45 | echo "Unknown mode: '$env:mode'" 46 | Exit 1 47 | } 48 | } else { 49 | $env:version="2.13.6" 50 | clearIvyCache 51 | # By default, test building the packages (but don't uplaod) 52 | # Need to redirect stderr, otherwise any error output (like jvm warning) fails the build (ErrorActionPreference) 53 | & cmd /c "sbt ""-Dproject.version=$env:version"" ""show s3Upload/mappings""" '2>&1' 54 | checkExit 55 | } 56 | -------------------------------------------------------------------------------- /admin/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | # Encrypting files (if you need to encrypt a new file but no longer have the secret, create a new 6 | # secret and re-encrypt all files): 7 | # 8 | # 1. Generate secret 9 | # cat /dev/urandom | head -c 10000 | openssl sha1 > ./secret 10 | # 2. Save the secret on travis 11 | # travis encrypt "PRIV_KEY_SECRET=$(cat ./secret)" 12 | # 3. Encrypt the file 13 | # openssl aes-256-cbc -pass "file:./secret" -in jenkins_lightbend_chara -out jenkins_lightbend_chara.enc 14 | # 4. Decrypt the file 15 | # openssl aes-256-cbc -d -pass "pass:$PRIV_KEY_SECRET" -in admin/files/jenkins_lightbend_chara.enc > ~/.ssh/jenkins_lightbend_chara 2>/dev/null 16 | 17 | function ensureVersion() { 18 | local verPat="[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)?" 19 | [[ "$version" =~ $verPat ]] || { 20 | echo "Not a valid Scala version: '$version'" 21 | exit 1 22 | } 23 | } 24 | 25 | function decrypt() { 26 | # Even though we're running bash with -x, travis hides the private key from the log 27 | openssl aes-256-cbc -d -pass "pass:$PRIV_KEY_SECRET" -in $1 > $2 2>/dev/null 28 | } 29 | 30 | function setupSSH() { 31 | mkdir -p ~/.ssh 32 | cp admin/files/ssh_config ~/.ssh/config 33 | echo 'chara.epfl.ch,128.178.154.107 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBLER9rqy0iCfz24+8BBBObh7FXXQJCoLLE9UuyQHNFUU4SS5FSzNjEoKXwTj8nqNy+8l0rOkj3KG8p2cLxsqjY=' >> ~/.ssh/known_hosts 34 | decrypt admin/files/jenkins_lightbend_chara.enc ~/.ssh/jenkins_lightbend_chara 35 | chmod 700 ~/.ssh && $(cd ~/.ssh && chmod 600 config known_hosts jenkins_lightbend_chara) 36 | } 37 | 38 | function triggerMsiRelease() { 39 | local jsonTemplate='{ "accountName": "scala", "projectSlug": "scala-dist", "branch": "%s", "commitId": "%s", "environmentVariables": { "mode": "%s", "version": "%s", "scala_sha": "%s" } }' 40 | local json=$(printf "$jsonTemplate" "$TRAVIS_BRANCH" "$TRAVIS_COMMIT" "$mode" "$version" "$scala_sha") 41 | 42 | local curlStatus=$(curl \ 43 | -s -o /dev/null -w "%{http_code}" \ 44 | -H "Authorization: Bearer $APPVEYOR_TOKEN" \ 45 | -H "Content-Type: application/json" \ 46 | -d "$json" \ 47 | https://ci.appveyor.com/api/builds) 48 | 49 | [[ "$curlStatus" == "200" ]] || { 50 | echo "Failed to start AppVeyor build" 51 | exit 1 52 | } 53 | } 54 | 55 | function triggerSmoketest() { 56 | local jsonTemplate='{ "request": { "branch": "%s", "message": "Smoketest %s", "config": { "before_install": "export version=%s scala_sha=%s" } } }' 57 | local json=$(printf "$jsonTemplate" "$TRAVIS_BRANCH" "$version" "$version" "$scala_sha") 58 | 59 | local curlStatus=$(curl \ 60 | -s -o /dev/null -w "%{http_code}" \ 61 | -H "Travis-API-Version: 3" \ 62 | -H "Authorization: token $TRAVIS_TOKEN" \ 63 | -H "Content-Type: application/json" \ 64 | -d "$json" \ 65 | https://api.travis-ci.com/repo/scala%2Fscala-dist-smoketest/requests) 66 | 67 | [[ "$curlStatus" == "202" ]] || { 68 | echo "Failed to start travis build" 69 | exit 1 70 | } 71 | } 72 | 73 | clearIvyCache() { 74 | rm -fv $HOME/.ivy2/exclude_classifiers $HOME/.ivy2/exclude_classifiers.lock 75 | rm -rfv $HOME/.ivy2/cache/org.scala-lang $HOME/.ivy2/cache/org.scala-lang.modules 76 | rm -rfv $HOME/.ivy2/local/org.scala-lang $HOME/.ivy2/local/org.scala-lang.modules 77 | if [ -d $HOME/.ivy2 ]; then find $HOME/.ivy2 -name "*compiler-interface*$version*" | xargs rm -rfv; fi 78 | if [ -d $HOME/.sbt ]; then find $HOME/.sbt -name "*compiler-interface*$version*" | xargs rm -rfv; fi 79 | } 80 | 81 | if [[ "$TRAVIS_EVENT_TYPE" == "api" ]]; then 82 | ensureVersion 83 | clearIvyCache 84 | if [[ "$mode" == "archives" ]]; then 85 | echo "Running 'archives' for $version" 86 | setupSSH 87 | . scripts/jobs/release/website/archives 88 | elif [[ "$mode" == "update-api" ]]; then 89 | echo "Running 'update-api' for $version" 90 | setupSSH 91 | . scripts/jobs/release/website/update-api 92 | elif [[ "$mode" == "release" ]]; then 93 | triggerMsiRelease 94 | if [[ "$version" =~ -bin- || "$version" =~ -pre- ]]; then 95 | # The log is too long for the travis UI, so remove ANSI codes to have a clean raw version 96 | sbt -Dsbt.log.noformat=true \ 97 | -Dproject.version=$version \ 98 | clean update "show s3Upload/mappings" 99 | else 100 | echo "Running a release for $version" 101 | # The log is too long for the travis UI, so remove ANSI codes to have a clean raw version 102 | sbt -Dsbt.log.noformat=true \ 103 | -Dproject.version=$version \ 104 | clean update ghUpload 105 | triggerSmoketest 106 | fi 107 | else 108 | echo "Unknown build mode: '$mode'" 109 | exit 1 110 | fi 111 | else 112 | version="2.13.6" 113 | clearIvyCache 114 | # By default, test building the packages (but don't uplaod) 115 | sbt -Dproject.version=$version "show s3Upload/mappings" 116 | fi 117 | -------------------------------------------------------------------------------- /admin/files/jenkins_lightbend_chara.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scala/scala-dist/914d7701dcf6b27b9c4942788e7da268940d2721/admin/files/jenkins_lightbend_chara.enc -------------------------------------------------------------------------------- /admin/files/ssh_config: -------------------------------------------------------------------------------- 1 | Host chara 2 | HostName chara.epfl.ch 3 | IdentityFile /home/travis/.ssh/jenkins_lightbend_chara 4 | User scalatest 5 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{build}' 2 | 3 | branches: 4 | only: 5 | - 2.11.x 6 | - 2.12.x 7 | - 2.13.x 8 | 9 | image: Visual Studio 2019 10 | 11 | environment: 12 | # java 11+ needed for sttp 13 | JAVA_HOME: C:\Program Files\Java\jdk21 14 | AWS_ACCESS_KEY_ID: 15 | secure: X1Ix1soRBDMtfbi8IFNPOggDP2XquhW+uKcJ+XC0kiM= 16 | AWS_SECRET_ACCESS_KEY: 17 | secure: woXwpM2+P3uZ1+LFM+SbJEKLfi7Kax5PvqJSN62nn1PQrJgEzVUAIoRGoXBx6X72 18 | GITHUB_OAUTH_TOKEN: 19 | secure: nfWNfbyzNQwdg1eWHZX93XIJLoAhFOr1fR8+L86s7a3jdo/HydEZ8TyEKsPipQ+/ 20 | 21 | install: 22 | - cmd: choco install sbt --version=1.10.11 -ia "INSTALLDIR=""C:\sbt""" 23 | - cmd: SET PATH=C:\sbt\bin;%JAVA_HOME%\bin;%PATH% 24 | 25 | build_script: 26 | - ps: . .\scripts\common.ps1 27 | - ps: postCommitStatus "pending" 28 | - ps: .\admin\build.ps1 29 | 30 | on_success: 31 | - ps: postCommitStatus "success" 32 | 33 | on_failure: 34 | - ps: postCommitStatus "failure" 35 | 36 | cache: 37 | - C:\sbt 38 | - C:\Users\appveyor\.sbt 39 | - C:\Users\appveyor\.ivy2 40 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | import ScalaDist.{s3Upload, ghUpload} 2 | 3 | resolvers += "scala-integration" at "https://scala-ci.typesafe.com/artifactory/scala-integration/" 4 | 5 | // so we don't require a native git install 6 | useJGit 7 | 8 | // The version of this build determines the Scala version to package. 9 | // We look at the closest git tag that matches v[0-9].* to derive it. 10 | // For testing, the version may be overridden with -Dproject.version=... 11 | versionWithGit 12 | 13 | isSnapshot := { 14 | git.overrideVersion(git.versionProperty.value) match { 15 | case Some(v) => v.endsWith("-SNAPSHOT") || git.gitUncommittedChanges.value 16 | case _ => isSnapshot.value // defined in SbtGit.scala 17 | } 18 | } 19 | 20 | Versioning.settings 21 | 22 | // necessary since sbt 0.13.12 for some dark and mysterious reason 23 | // perhaps related to sbt/sbt#2634. details, to the extent they 24 | // are known/understood, at scala/scala-dist#171 25 | scalaVersion := version.value 26 | 27 | s3Upload / mappings := Seq() 28 | 29 | s3Upload := { 30 | import com.amazonaws.services.s3.AmazonS3ClientBuilder 31 | import com.amazonaws.services.s3.model.PutObjectRequest 32 | import com.amazonaws.regions.Regions 33 | 34 | // The standard client picks credentials from AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY env vars 35 | val client = AmazonS3ClientBuilder.standard.withRegion(Regions.US_EAST_1).build 36 | 37 | val log = streams.value.log 38 | (s3Upload / mappings).value map { case (file, key) => 39 | log.info("Uploading "+ file.getAbsolutePath() +" as "+ key) 40 | client.putObject(new PutObjectRequest("downloads.typesafe.com", key, file)) 41 | } 42 | } 43 | 44 | ghUpload := { 45 | import sttp.client3._ 46 | import _root_.io.circe._, _root_.io.circe.parser._ 47 | import scala.concurrent.duration._ 48 | 49 | val log = streams.value.log 50 | val ghRelease = s"v${(Universal / version).value}" 51 | 52 | val token = sys.env.getOrElse("GITHUB_OAUTH_TOKEN", throw new MessageOnlyException("GITHUB_OAUTH_TOKEN missing")) 53 | 54 | val backend = HttpURLConnectionBackend() 55 | 56 | val rRes = basicRequest 57 | .get(uri"https://api.github.com/repos/scala/scala/releases/tags/$ghRelease") 58 | .header("Accept", "application/vnd.github+json") 59 | .header("Authorization", s"Bearer $token") 60 | .header("X-GitHub-Api-Version", "2022-11-28") 61 | .send(backend) 62 | val releaseId = rRes.body.flatMap(parse).getOrElse(Json.Null).hcursor.downField("id").as[Int].getOrElse( 63 | throw new MessageOnlyException(s"Release not found: $ghRelease")) 64 | 65 | (s3Upload / mappings).value map { case (file, _) => 66 | log.info(s"Uploading ${file.getAbsolutePath} as ${file.getName} to https://github.com/scala/scala/releases/tag/$ghRelease") 67 | 68 | // https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#upload-a-release-asset 69 | val response = basicRequest 70 | .post(uri"https://uploads.github.com/repos/scala/scala/releases/${releaseId}/assets?name=${file.getName}") 71 | .contentType("application/octet-stream") 72 | .header("Accept", "application/vnd.github+json") 73 | .header("Authorization", s"Bearer $token") 74 | .header("X-GitHub-Api-Version", "2022-11-28") 75 | .body(file) 76 | .readTimeout(15.minutes) // .deb is 650+ MB (API docs are not zipped... scala/scala-dist#189) 77 | .send(backend) 78 | 79 | if (response.code.code != 201) 80 | throw new MessageOnlyException(s"Upload failed: status=${response.code}\n${response.body}") 81 | } 82 | } 83 | 84 | ScalaDist.settings 85 | 86 | Docs.settings 87 | 88 | ScalaDist.platformSettings 89 | 90 | enablePlugins(UniversalPlugin, RpmPlugin, JDebPackaging, WindowsPlugin) 91 | 92 | // TODO This silences a warning I don't understand. 93 | // 94 | // * scala-dist / Universal / configuration 95 | // +- /Users/jz/code/scala-dist/build.sbt:35 96 | // * scala-dist / Universal-docs / configuration 97 | // +- /Users/jz/code/scala-dist/build.sbt:35 98 | // * scala-dist / Universal-src / configuration 99 | // +- /Users/jz/code/scala-dist/build.sbt:35 100 | Global / excludeLintKeys += configuration 101 | 102 | // resolvers += "local" at "file:///e:/.m2/repository" 103 | // resolvers += Resolver.mavenLocal 104 | // to test, run e.g., stage, or windows:packageBin, show s3Upload::mappings 105 | -------------------------------------------------------------------------------- /project/Docs.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | 4 | import com.typesafe.sbt.SbtNativePackager._ 5 | import com.typesafe.sbt.packager.Keys._ 6 | 7 | /** Create mappings for UniversalDocs under the api/ directory. 8 | * 9 | * All dependencies of scala-dist under the javadoc classifier are included as 10 | * "api/jars/$artifactId-$version-javadoc.jar". 11 | * 12 | * The core jars are also expanded under api/scala-{library|reflect|compiler} 13 | * 14 | */ 15 | object Docs { 16 | import ScalaDist._ 17 | 18 | def settings: Seq[Setting[_]] = Seq( 19 | UniversalDocs / packageName := s"scala-docs-${version.value}", 20 | // libraryDependencies += scalaDistDep(version.value, "javadoc"), // seems not to be necessary 21 | // need updateClassifiers to get javadoc jars 22 | UniversalDocs / mappings ++= createMappingsWith(updateClassifiers.value.toSeq, universalDocsMappings) 23 | ) 24 | 25 | private def universalDocsMappings(id: ModuleID, artifact: Artifact, file: File): Seq[(File, String)] = { 26 | def includeJar = (file -> s"api/jars/${id.name}-${id.revision}-javadoc.jar") 27 | artifact.name match { 28 | case "scala-library" | "scala-reflect" | "scala-compiler" if artifact.`type` == "doc" => 29 | val tmpdir = IO.createTemporaryDirectory 30 | IO.unzip(file, tmpdir) 31 | // IO.listFiles(tmpdir) does not recurse, use ** with glob "*" to find all files 32 | val exploded = (PathFinder(IO.listFiles(tmpdir)) ** "*").get flatMap { file => 33 | val relative = IO.relativize(tmpdir, file).get // .get is safe because we just unzipped under tmpdir 34 | 35 | Seq(file -> s"api/${id.name}/$relative") 36 | } 37 | includeJar +: exploded 38 | case _ if artifact.`type` == "doc" => 39 | Seq(includeJar) 40 | case _ => Seq() 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /project/ScalaDist.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | 4 | import com.typesafe.sbt.SbtNativePackager._ 5 | import com.typesafe.sbt.packager.MappingsHelper._ 6 | import com.typesafe.sbt.packager.universal.UniversalPlugin.autoImport.useNativeZip 7 | import com.typesafe.sbt.packager.Keys._ 8 | 9 | import com.amazonaws.services.s3.model.PutObjectResult 10 | 11 | // can't call it Universal -- that's taken by the packager 12 | object ScalaDist { 13 | val s3Upload = TaskKey[Seq[PutObjectResult]]("s3Upload","Uploads files to an S3 bucket.") 14 | val ghUpload = TaskKey[Seq[Unit]]("ghUpload","Uploads files to GitHub Releases.") 15 | 16 | def createMappingsWith(deps: Seq[(sbt.librarymanagement.ConfigRef, ModuleID, Artifact, File)], 17 | distMappingGen: (ModuleID, Artifact, File) => Seq[(File, String)]): Seq[(File, String)] = 18 | deps flatMap { 19 | case (configRef, id, artifact, file) 20 | if configRef.name == ScalaDistConfigName && id.configurations.contains("runtime") => 21 | distMappingGen(id, artifact, file) 22 | case _ => Seq() 23 | } 24 | 25 | // used to make s3Upload upload the file produced by fileTask to the path scala/$version/${file.name} 26 | private def uploadMapping(fileTask: TaskKey[File]) = Def.task { 27 | val file = fileTask.value 28 | file -> s"scala/${version.value}/${file.getName}" 29 | } 30 | 31 | // make it so that s3Upload will upload the msi when we're running on windows, and everything else when we're on linux 32 | // s3Upload thus depends on the package tasks listed below 33 | def platformSettings = 34 | if (sys.props("os.name").toLowerCase(java.util.Locale.US) contains "windows") 35 | Wix.settings :+ (s3Upload / mappings += uploadMapping(Windows / packageBin).value) 36 | else Unix.settings ++ Seq( 37 | s3Upload / mappings += uploadMapping(Universal / packageBin).value, 38 | s3Upload / mappings += uploadMapping(Universal / packageZipTarball).value, 39 | s3Upload / mappings += uploadMapping(UniversalDocs / packageBin).value, 40 | s3Upload / mappings += uploadMapping(UniversalDocs / packageZipTarball).value, 41 | s3Upload / mappings += uploadMapping(UniversalDocs / packageXzTarball).value, 42 | s3Upload / mappings += uploadMapping(Rpm / packageBin).value, 43 | // Debian needs special handling because the value sbt-native-packager 44 | // gives us for `Debian / packageBin` (coming from the archiveFilename 45 | // method) includes the debian version and arch information, 46 | // which we historically have not included. I don't see a way to 47 | // override the filename on disk, so we re-map at upload time 48 | s3Upload / mappings += Def.task { 49 | (Debian / packageBin).value -> 50 | s"scala/${version.value}/${(Debian / name).value}-${version.value}.deb" 51 | }.value 52 | ) 53 | 54 | def settings: Seq[Setting[_]] = 55 | useNativeZip ++ // use native zip to preserve +x permission on scripts 56 | Seq( 57 | name := "scala", 58 | maintainer := "LAMP/EPFL and Akka", 59 | packageSummary := "Scala Programming Language Distribution", // this will be spliced into the middle of a sentence --> no period (it also determines sort order, so, no "The" in front) 60 | packageDescription := "Have the best of both worlds. Construct elegant class hierarchies for maximum code reuse and extensibility, implement their behavior using higher-order functions. Or anything in-between.", 61 | crossPaths := false, 62 | 63 | ivyConfigurations += ScalaDistConfig, 64 | libraryDependencies += scalaDistDep(version.value, "runtime"), 65 | 66 | // create lib directory by resolving scala-dist's dependencies 67 | // to populate the rest of the distribution, explode scala-dist artifact itself 68 | Universal / mappings ++= createMappingsWith(update.value.toSeq, universalMappings), 69 | ) 70 | 71 | // private lazy val onWindows = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("windows") 72 | // only used for small batch files, normalize line endings in-place 73 | // private def toDosInPlace(f: File) = IO.writeLines(file, IO.readLines(file)) 74 | 75 | private lazy val ScalaDistConfigName = "scala-dist" 76 | private lazy val ScalaDistConfig = config(ScalaDistConfigName) 77 | // segregate scala-dist's compile dependencies into the scala-dist config 78 | private def scalaDistDep(v: String, config: String): ModuleID = 79 | "org.scala-lang" % "scala-dist" % v % s"${ScalaDistConfigName}; ${ScalaDistConfigName}->${config}" 80 | 81 | // map module to the corresponding file mappings (unzipping scala-dist in the process) 82 | private def universalMappings(id: ModuleID, artifact: Artifact, file: File): Seq[(File, String)] = id.name match { 83 | // scala-dist: explode (drop META-INF/) 84 | case "scala-dist" => 85 | val tmpdir = IO.createTemporaryDirectory 86 | IO.unzip(file, tmpdir) 87 | 88 | // create mappings from the unzip scala-dist zip 89 | contentOf(tmpdir) filter { 90 | case (_, dest) => !(dest.endsWith("MANIFEST.MF") || dest.endsWith("META-INF")) 91 | } map { 92 | // make unix scripts executable (heuristically...) 93 | case (file, dest) if (dest startsWith "bin/") && !(dest endsWith ".bat") => 94 | file.setExecutable(true, true) 95 | file -> dest 96 | case mapping => mapping 97 | } 98 | 99 | // core jars: use simple name for backwards compat 100 | case "scala-library" | "scala-reflect" | "scala-compiler" => 101 | Seq(file -> s"lib/${id.name}.jar") 102 | 103 | // other artifacts: qualify with version etc (they're also binary cross versioned) 104 | // TODO: prefix with ${id.organization} when it doesn't start with org.scala-lang/akka/com.typesafe? 105 | case _ => 106 | Seq(file -> s"lib/${id.name}-${id.revision}.jar") 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /project/Unix.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | 4 | import com.typesafe.sbt.SbtNativePackager._ 5 | import com.typesafe.sbt.packager.Keys._ 6 | import com.typesafe.sbt.packager.linux.{LinuxPackageMapping => pkgMap, LinuxSymlink} 7 | import com.typesafe.sbt.packager.linux.LinuxPlugin.autoImport.packageMapping 8 | 9 | /** Create debian & rpm packages. 10 | * 11 | * subdirs not requiring special treatment are rooted under `installTargetUnix.value` 12 | * docs go to `installTargetUnixDocs.value` 13 | * create symlinks under /usr/bin/ for all scripts in `installTargetUnix.value / "bin"` 14 | * make scripts in `installTargetUnix.value / "bin"` executable, drop ".bat" files 15 | * map man to /usr/share/man/ 16 | * map doc to `installTargetUnixDocs.value` 17 | * map api to `installTargetUnixDocs.value / "api"` 18 | */ 19 | object Unix { 20 | val installTargetUnix = SettingKey[File]("install-target-unix", "The location where we will install Scala.") 21 | val installTargetUnixDocs = SettingKey[File]("install-target-docs-unix", "The location where we will install the Scala docs.") 22 | 23 | def settings = Seq ( 24 | installTargetUnix := file("/usr/share/scala"), 25 | installTargetUnixDocs := file("/usr/share/doc/scala"), 26 | 27 | // symlinks for s"/usr/bin/$script" --> s"${installTargetUnix.value}/bin/$script" 28 | // TODO: reuse code from native packager 29 | linuxPackageSymlinks ++= ( 30 | (Universal / mappings).value collect { 31 | case (file, name) if (name startsWith "bin/") && !(name endsWith ".bat") => 32 | LinuxSymlink("/usr/" + name, (installTargetUnix.value / name).getAbsolutePath) 33 | } 34 | ), 35 | 36 | linuxPackageMappings ++= { 37 | def home(name: String) = (installTargetUnix.value / name).getAbsolutePath 38 | def docHome(name: String) = (installTargetUnixDocs.value / name).getAbsolutePath 39 | 40 | val m = (Universal / mappings).value 41 | 42 | // some mappings need special treatment (different root, perms,...) 43 | val (special, regular) = m partition { case (file, name) => 44 | (name startsWith "bin") || (name startsWith "doc") || (name startsWith "man") 45 | } 46 | val docs = (UniversalDocs / mappings).value 47 | 48 | Seq( 49 | // no special treatment needed 50 | (pkgMap(regular map { case (file, name) => file -> home(name) }) 51 | withPerms "0644"), 52 | // make scripts in bin/ executable, drop .bat files 53 | (pkgMap(special collect { case (file, name) if (name startsWith "bin/") && !(name endsWith ".bat") => file -> home(name) }) 54 | withPerms "0755"), 55 | // mappings for man/ --> /usr/share/man/ 56 | (pkgMap(special collect { case (file, name) if name startsWith "man/" => file -> s"/usr/share/$name.gz"}) 57 | withPerms "0644").gzipped.asDocs, 58 | // mappings for doc/ --> /usr/share/doc/scala/ and api/ --> /usr/share/doc/scala/api/ 59 | (pkgMap( 60 | (special collect { case (file, name) if name startsWith "doc/" => file -> docHome(name drop 4) }) ++ 61 | (docs map { case (file, name) => file -> docHome(name) }) :+ 62 | (((Linux / sourceDirectory).value / "copyright") -> docHome("copyright"))) 63 | withPerms "0644").asDocs 64 | ) 65 | }, 66 | 67 | // RPM Specific 68 | Rpm / name := "scala", 69 | rpmVendor := "akka", 70 | rpmUrl := Some("https://github.com/scala/scala"), 71 | rpmLicense := Some("Apache 2"), 72 | rpmGroup := Some("Development/Languages"), 73 | 74 | // This hack lets us ignore the RPM specific versioning junks. 75 | Rpm / packageBin := { 76 | val simplified = target.value / s"${(Rpm / name).value}-${version.value}.rpm" 77 | 78 | val rpm = (Rpm / packageBin).value match { 79 | case reported if reported.exists => reported 80 | case _ => // hack on top of hack because RpmHelper.buildRpm is broken on Mac -- `spec.meta.arch` doesn't necessarily match the arch `rpmbuild` decided on 81 | (PathFinder(IO.listFiles((Rpm / target).value)) ** "*.rpm").get.find(file => 82 | file.getName contains (Rpm / name).value).get 83 | } 84 | 85 | IO.copyFile(rpm, simplified) 86 | simplified 87 | }, 88 | 89 | // Debian Specific 90 | Debian / name := "scala", 91 | debianPackageDependencies += "java8-runtime-headless", 92 | 93 | Debian / linuxPackageMappings += (packageMapping( 94 | (sourceDirectory.value / "debian" / "changelog") -> "/usr/share/doc/scala/changelog.gz" 95 | ).withUser("root").withGroup("root").withPerms("0644").gzipped).asDocs() 96 | 97 | ) 98 | } 99 | -------------------------------------------------------------------------------- /project/Versioning.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | 4 | import com.typesafe.sbt.SbtNativePackager.{Windows, Debian, Rpm} 5 | 6 | object Versioning { 7 | def settings: Seq[Setting[_]] = Seq( 8 | Windows / version := makeWindowsVersion(version.value), 9 | Debian / version := toDebianVersion((Windows / version).value), 10 | Rpm / version := toRpmVersion((Windows / version).value)) 11 | 12 | private def rpmBuild(version:String): String = version split "\\." match { 13 | case Array(_,_,_, b) => b 14 | case _ => "1" 15 | } 16 | 17 | private def toRpmVersion(version:String): String = version split "\\." match { 18 | case Array(m,n,b,_*) => s"$m.$n.$b" 19 | case _ => version 20 | } 21 | 22 | private def toDebianVersion(version:String): String = version split "\\." match { 23 | case Array(m,n,b,z) => s"$m.$n.$b-$z" 24 | case _ => version 25 | } 26 | 27 | // This is a complicated means to convert maven version numbers into monotonically increasing windows versions. 28 | private def makeWindowsVersion(version: String): String = { 29 | val Majors = """(\d+).(\d+).(\d+)(-.*)?""".r 30 | val Rcs = """(-\d+)?-RC(\d+)""".r 31 | val Milestones = """(-\d+)?-M(\d+)""".r 32 | val BuildNum = """-(\d+)""".r 33 | 34 | def calculateNumberFour(buildNum: Int = 0, rc: Int = 0, milestone: Int = 0) = 35 | if (rc > 0 || milestone > 0) (buildNum)*400 + rc*20 + milestone 36 | else (buildNum+1)*400 + rc*20 + milestone 37 | 38 | version match { 39 | case Majors(major, minor, bugfix, rest) => 40 | s"$major.$minor.$bugfix." + (rest match { 41 | case null => calculateNumberFour(0,0,0) 42 | case Milestones(null, num) => calculateNumberFour(0,0,num.toInt) 43 | case Milestones(bnum, num) => calculateNumberFour(bnum.drop(1).toInt,0,num.toInt) 44 | case Rcs(null, num) => calculateNumberFour(0,num.toInt,0) 45 | case Rcs(bnum, num) => calculateNumberFour(bnum.drop(1).toInt,num.toInt,0) 46 | case BuildNum(bnum) => calculateNumberFour(bnum.toInt,0,0) 47 | case _ => calculateNumberFour(0,0,0) 48 | }) 49 | case x => x 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /project/Wix.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | 4 | import com.typesafe.sbt.SbtNativePackager._ 5 | import com.typesafe.sbt.packager.Keys._ 6 | 7 | import com.typesafe.sbt.packager.windows._ 8 | import WixHelper.{generateComponentsAndDirectoryXml, cleanFileName} 9 | 10 | // can't call it Windows, that's a config name 11 | object Wix { 12 | // Windows installer configuration 13 | def settings: Seq[Setting[_]] = Seq( 14 | Windows / mappings := (Universal / mappings).value, 15 | // Windows / distributionFiles += (Windows / packageMsi).value, 16 | 17 | wixProductId := "7606e6da-e168-42b5-8345-b08bf774cb30", 18 | wixProductUpgradeId := "6061c134-67c7-4fb2-aff5-32b01a186968", 19 | // wixProductComments := "Scala Programming language for use in Windows.", 20 | 21 | wixProductConfig := makeProductConfig((Universal / stagingDirectory).value, (UniversalDocs / stagingDirectory).value), 22 | wixProductConfig := (wixProductConfig 23 | dependsOn (Universal / stage) 24 | dependsOn (UniversalDocs / stage)).value, 25 | 26 | Windows / packageBin := { 27 | val versioned = target.value / s"${name.value}-${version.value}.msi" 28 | 29 | IO.copyFile((Windows / packageBin).value, versioned) 30 | versioned 31 | } 32 | ) 33 | 34 | private def makeProductConfig(stage: File, stageApi: File) = { 35 | 36 | // there are deprecation warnings here. the methods have been undeprecated 37 | // at https://github.com/sbt/sbt-native-packager/pull/909 . once we upgrade 38 | // to a newer sbt-native-packager that includes that change, we could 39 | // enable -Xfatal-warnings again in scalacOptions in project/plugins.sbt 40 | val (bin, binDirXml0) = generateComponentsAndDirectoryXml(stage / "bin") 41 | val (doc, docDirXml) = generateComponentsAndDirectoryXml(stage / "doc", "doc_") 42 | val (lib, libDirXml) = generateComponentsAndDirectoryXml(stage / "lib", "lib_") 43 | val (api, apiDirXml) = generateComponentsAndDirectoryXml(stageApi / "api", "api_") 44 | 45 | // add component that adds bin folder to path 46 | val binDirXml = binDirXml0 match { 47 | case d@({files@_*}) => 48 | 49 | {files} 50 | 51 | 52 | 53 | 54 | 55 | } 56 | 57 | val directoriesXml = binDirXml ++ libDirXml ++ docDirXml ++ apiDirXml 58 | 59 | def componentRefs(refs: Seq[String]) = refs map {ref => } 60 | val core = (bin ++ lib ++ doc) 61 | 62 | val apiDirId = apiDirXml \ "@Id" 63 | val apiIndex = s"""[$apiDirId]scala-library\\index.html""" 64 | // TODO: create (advertised?) shortcut to other api subdirs and to repl -- man, why is this so hard? 65 | // val scalaRepl = """[INSTALLDIR]\bin\scala.bat""" 66 | val licensePath = cleanFileName((stage / "doc" / "License.rtf").getAbsolutePath) 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | { directoriesXml } 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | { componentRefs(core) } 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | { componentRefs(api) } 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.10.11 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | scalacOptions ++= Seq("-deprecation", "-feature", "-Xlint:_,-unused") 2 | 3 | // jdeb and spotify docker are 'provided' in sbt-native-packager 4 | libraryDependencies += "org.vafer" % "jdeb" % "1.9" artifacts (Artifact("jdeb", "jar", "jar")) 5 | libraryDependencies += "com.spotify" % "docker-client" % "8.16.0" 6 | addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.8.1") 7 | 8 | libraryDependencies += "com.amazonaws" % "aws-java-sdk-s3" % "1.12.5" 9 | 10 | libraryDependencies += "com.softwaremill.sttp.client3" %% "core" % "3.11.0" 11 | libraryDependencies ++= Seq( 12 | "io.circe" %% "circe-core", 13 | "io.circe" %% "circe-generic", 14 | "io.circe" %% "circe-parser" 15 | ).map(_ % "0.14.13") 16 | 17 | addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.1") 18 | -------------------------------------------------------------------------------- /scripts/common: -------------------------------------------------------------------------------- 1 | # https://github.com/travis-ci/docs-travis-ci-com/issues/949 2 | function travis_fold_start() { 3 | echo "" 4 | echo -e "travis_fold:start:$1\033[33;1m$2\033[0m" 5 | } 6 | 7 | function travis_fold_end() { 8 | echo -e "\ntravis_fold:end:$1\r" 9 | echo "" 10 | } 11 | 12 | # Params: 13 | # - state: pending / success / failed / error 14 | function postCommitStatus() { 15 | if [[ "$scala_sha" != "" ]]; then 16 | local jsonTemplate='{ "state": "%s", "target_url": "%s", "description": "%s", "context": "%s"}' 17 | local json=$(printf "$jsonTemplate" "$1" "https://app.travis-ci.com/github/scala/scala-dist/builds/$TRAVIS_BUILD_ID" "$1" "travis/scala-dist/$version/$mode") 18 | [[ -z "$GITHUB_OAUTH_TOKEN" ]] && (echo "Missing environment variable GITHUB_OAUTH_TOKEN!"; exit 1) 19 | TMPFILE=$(mktemp -t curl.XXXXXXXXXX) 20 | 21 | local tmpfile=$(mktemp -t curl.XXXXXXXXXX) || exit 1 22 | 23 | local curlStatus=$(curl \ 24 | -s -o $tmpfile -w "%{http_code}" \ 25 | -H "Accept: application/vnd.github.v3+json" \ 26 | -H "Authorization: token $GITHUB_OAUTH_TOKEN" \ 27 | -d "$json" \ 28 | https://api.github.com/repos/scala/scala/statuses/$scala_sha) 29 | 30 | [[ "$curlStatus" == "201" ]] || { 31 | echo "Failed to publish GitHub commit status. Got: $curlStatus" 32 | cat $tmpfile 33 | exit 1 34 | } 35 | fi 36 | } 37 | -------------------------------------------------------------------------------- /scripts/common.ps1: -------------------------------------------------------------------------------- 1 | $homeDir="C:\Users\appveyor" 2 | 3 | Function postCommitStatus($state) { 4 | if ("$env:scala_sha" -ne "") { 5 | $jsonTemplate = '{{ "state": "{0}", "target_url": "{1}", "description": "{2}", "context": "{3}" }}' 6 | $json = "$jsonTemplate" -f "$state", "https://ci.appveyor.com/project/scala/scala-dist/build/$env:APPVEYOR_BUILD_NUMBER", "$state", "appveyor/scala-dist/$env:version/$env:mode" 7 | 8 | # https://stackoverflow.com/questions/41618766/powershell-invoke-webrequest-fails-with-ssl-tls-secure-channel 9 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 10 | 11 | $respone = Invoke-WebRequest ` 12 | "https://api.github.com/repos/scala/scala/statuses/$env:scala_sha" ` 13 | -Method 'POST' ` 14 | -Body "$json" ` 15 | -Headers @{"Accept"="application/vnd.github.v3+json"; "Authorization"="token $env:GITHUB_OAUTH_TOKEN"} ` 16 | -UseBasicParsing 17 | 18 | if ($respone.StatusCode -ne 201) { 19 | echo "Failed to publish GitHub commit status" 20 | Exit 1 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/jobs/release/website/archives: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | url="https://downloads.lightbend.com/scala/$version" 4 | 5 | if [[ "$version" =~ ^.*-(bin|pre)-[0-9a-f]+$ ]] 6 | then archivesDir="~linuxsoft/archives/scala/nightly/2.13.x" 7 | else archivesDir="~linuxsoft/archives/scala" 8 | fi 9 | 10 | # make this build restartable (if interrupted, partial files may remain, and resuming isn't very reliable) 11 | [[ -n $version ]] && ssh chara "rm -f $archivesDir/scala-*$version* && rm -rf $archivesDir/api/$version/ ||:" 12 | 13 | cacheBuster="$(date +%s | tail -c2 | head -c1)" 14 | ssh chara "cd $archivesDir && wget -nv -O scala-$version.msi '$url/scala-$version.msi?$cacheBuster'" 15 | ssh chara "cd $archivesDir && wget -nv -O scala-$version.zip '$url/scala-$version.zip?$cacheBuster'" 16 | ssh chara "cd $archivesDir && wget -nv -O scala-$version.tgz '$url/scala-$version.tgz?$cacheBuster'" 17 | ssh chara "cd $archivesDir && wget -nv -O scala-$version.deb '$url/scala-$version.deb?$cacheBuster'" 18 | ssh chara "cd $archivesDir && wget -nv -O scala-$version.rpm '$url/scala-$version.rpm?$cacheBuster'" 19 | ssh chara "cd $archivesDir && wget -nv -O scala-docs-$version.zip '$url/scala-docs-$version.zip?$cacheBuster'" 20 | ssh chara "cd $archivesDir && wget -nv -O scala-docs-$version.tgz '$url/scala-docs-$version.tgz?$cacheBuster'" 21 | ssh chara "cd $archivesDir && wget -nv -O scala-docs-$version.txz '$url/scala-docs-$version.txz?$cacheBuster'" 22 | 23 | echo "Expanding scala-library API docs for $version to api/$version (with subdirectories for scala-compiler and scala-reflect)." 24 | ssh chara "cd $archivesDir && mkdir -p api/$version && tar -xvz --strip-component 2 -f scala-docs-$version.tgz -C api/$version && mv api/$version/scala-library/* api/$version/" # tar on jenkins does not support the -s option 25 | -------------------------------------------------------------------------------- /scripts/jobs/release/website/update-api: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | if [[ "$version" =~ ^.*-(bin|pre)-[0-9a-f]+$ ]] 4 | then archivesDir="~linuxsoft/archives/scala/nightly/2.13.x" 5 | else archivesDir="~linuxsoft/archives/scala" 6 | fi 7 | 8 | echo "Symlinking $archivesDir/api/$version to $archivesDir/api/2.13.x." 9 | 10 | ssh chara "cd $archivesDir/api/ ; [[ -d $version ]] && ln -sfn $version 2.13.x" 11 | 12 | # needs to run once on new major release: 13 | # ssh chara "cd $archivesDir/api/ ; [[ -d $version ]] && ln -sfn 2.13.x current" 14 | -------------------------------------------------------------------------------- /src/debian/changelog: -------------------------------------------------------------------------------- 1 | 2 | scala (2.9.2-build-001) 3 | 4 | * First debian package release 5 | 6 | -- Joshua Suereth 2012-01-27 7 | -------------------------------------------------------------------------------- /src/linux/copyright: -------------------------------------------------------------------------------- 1 | Scala 2 | Copyright (c) 2002-2025 EPFL 3 | Copyright (c) 2011-2025 Lightbend, Inc. dba Akka 4 | 5 | Scala includes software developed at 6 | LAMP/EPFL (https://lamp.epfl.ch/) and 7 | Akka. (https://akka.io/). 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"). 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | This software includes projects with other licenses -- see `doc/LICENSE.md`. 17 | --------------------------------------------------------------------------------