Compare commits

..

1 Commits
v2.2 ... v1.6

Author SHA1 Message Date
Sascha Mann
ee66464cb7 Add production dependencies & build 2021-08-05 16:38:38 +02:00
28 changed files with 12950 additions and 34463 deletions

View File

@@ -3,6 +3,7 @@ name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: "[BUG] " title: "[BUG] "
labels: bug labels: bug
assignees: SaschaMann
--- ---

View File

@@ -3,17 +3,5 @@ updates:
- package-ecosystem: gitsubmodule - package-ecosystem: gitsubmodule
directory: "/" directory: "/"
schedule: schedule:
interval: monthly interval: daily
open-pull-requests-limit: 99 open-pull-requests-limit: 10
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'monthly'
open-pull-requests-limit: 99
- package-ecosystem: npm
directory: "/"
schedule:
interval: monthly
open-pull-requests-limit: 99

View File

@@ -1,11 +0,0 @@
if !occursin("hostedtoolcache", Sys.BINDIR)
error("the wrong julia is being used: $(Sys.BINDIR)")
end
if VERSION >= v"1.7.0" # pkgdir was introduced here, and before then mtime wasn't a problem so just skip
using Pkg
src = pkgdir(Pkg, "src", "Pkg.jl")
# mtime is when it's compressed, ctime is when the file is extracted
if mtime(src) >= ctime(src)
error("source mtime ($(mtime(src))) is not earlier than ctime ($(ctime(src)))")
end
end

33
.github/workflows/backup.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Backup
on:
schedule:
- cron: '5 4 * * 0'
workflow_dispatch:
jobs:
backup:
runs-on: ubuntu-20.04
steps:
- name: Configure cache
uses: actions/cache@v2
with:
path: |
${{ env.GITHUB_WORKSPACE }}
~/.cache/restic
key: ${{ runner.os }}
- name: Install the correct Python version
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Run backup action
uses: julia-actions/restic-action@main
env: # Options: https://restic.readthedocs.io/en/latest/040_backup.html#environment-variables
RESTIC_REPOSITORY: b2:${{ secrets.B2_BUCKET }}:${{ github.repository }}
RESTIC_PASSWORD: ${{ secrets.RESTIC_PASSWORD }}
B2_ACCOUNT_ID: ${{ secrets.B2_ACCOUNT_ID }}
B2_ACCOUNT_KEY: ${{ secrets.B2_ACCOUNT_KEY }}

View File

@@ -1,22 +1,11 @@
name: "PR Checks" name: "PR Checks"
on: [pull_request, push] on: [pull_request, push]
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
jobs: jobs:
check_pr: check_pr:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 60
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v1
- uses: actions/setup-node@v4
with:
node-version-file: '.tool-versions'
- name: "npm ci" - name: "npm ci"
run: npm ci run: npm ci

View File

@@ -11,12 +11,6 @@
# #
name: "CodeQL" name: "CodeQL"
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on: on:
push: push:
branches: [ master, releases/* ] branches: [ master, releases/* ]
@@ -30,7 +24,6 @@ jobs:
analyze: analyze:
name: Analyze name: Analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 60
strategy: strategy:
fail-fast: false fail-fast: false
@@ -42,11 +35,11 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@v1
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@@ -57,7 +50,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v3 uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@@ -71,4 +64,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3 uses: github/codeql-action/analyze@v1

View File

@@ -1,48 +0,0 @@
name: Example builds (default arch)
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on:
push:
branches: ['main', 'master', 'releases/*']
pull_request:
workflow_dispatch:
jobs:
test:
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
julia-version: ['1']
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
if: ${{ ! startsWith(github.ref, 'refs/heads/releases') }}
with:
node-version-file: '.tool-versions'
- name: "Install dependencies"
if: ${{ ! startsWith(github.ref, 'refs/heads/releases') }}
run: |
npm install
npm run build
npm run pack
- name: "Set up Julia"
id: setup-julia
uses: ./
with:
version: ${{ matrix.julia-version }}
- run: julia --version
- run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'
- name: "Check that the correct julia is used and that archive mtimes are maintained"
run: julia --startup-file=no --color=yes ./.github/scripts/common-tests.jl

View File

@@ -1,53 +0,0 @@
name: Example builds (nightly, default arch)
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on:
push:
branches: ['main', 'master', 'releases/*']
pull_request:
jobs:
test:
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
julia-version: [nightly, 1.10-nightly]
os:
- ubuntu-latest
- windows-latest
# - macos-11 # Intel
- macos-12 # Intel
- macos-13 # Intel
- macos-14 # Apple Silicon
- macos-latest # Currently Intel, but will probably point to Apple Silicon in the future
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
if: ${{ ! startsWith(github.ref, 'refs/heads/releases') }}
with:
node-version-file: '.tool-versions'
- name: "Install dependencies"
if: ${{ ! startsWith(github.ref, 'refs/heads/releases') }}
run: |
npm install
npm run build
npm run pack
- name: "Set up Julia (${{ matrix.julia-version }})"
uses: ./
with:
version: ${{ matrix.julia-version }}
- run: julia --version
- run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'
- name: "Check that the correct julia is used and that archive mtimes are maintained"
run: julia --startup-file=no --color=yes ./.github/scripts/common-tests.jl

View File

@@ -1,11 +1,5 @@
name: Example builds (nightly) name: Example builds (nightly)
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on: on:
push: push:
branches: ['main', 'master', 'releases/*'] branches: ['main', 'master', 'releases/*']
@@ -16,28 +10,21 @@ on:
jobs: jobs:
test: test:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
julia-version: [nightly, 1.10-nightly] julia-version: [nightly, 1.7-nightly]
julia-arch: [x64, x86] julia-arch: [x64, x86]
os: [ubuntu-latest, macOS-latest, windows-latest] os: [ubuntu-latest, macOS-latest, windows-latest]
# 32-bit Julia binaries are not available on macOS # 32-bit Julia binaries are not available on macOS
exclude: exclude:
- os: macOS-latest - os: macOS-latest
julia-arch: x86 julia-arch: x86
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v1.0.0
- uses: actions/setup-node@v4
if: ${{ ! startsWith(github.ref, 'refs/heads/releases') }}
with:
node-version-file: '.tool-versions'
- name: "Install dependencies" - name: "Install dependencies"
if: ${{ ! startsWith(github.ref, 'refs/heads/releases') }}
run: | run: |
npm install npm install
npm run build npm run build
@@ -50,5 +37,3 @@ jobs:
arch: ${{ matrix.julia-arch }} arch: ${{ matrix.julia-arch }}
- run: julia --version - run: julia --version
- run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()' - run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'
- name: "Check that the correct julia is used and that archive mtimes are maintained"
run: julia --startup-file=no --color=yes ./.github/scripts/common-tests.jl

View File

@@ -1,42 +1,28 @@
name: Example builds name: Example builds
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on: on:
push: push:
branches: ['main', 'master', 'releases/*'] branches: ['main', 'master', 'releases/*']
pull_request: pull_request:
workflow_dispatch:
jobs: jobs:
test: test:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
julia-version: ['1.0.5', '1.2', '^1.5.0-beta1', '1', 'lts', 'pre'] julia-version: ['1.0.5', '1', '^1.5.0-beta1']
julia-arch: [x64, x86] julia-arch: [x64, x86]
os: [ubuntu-latest, macOS-latest, windows-latest] os: [ubuntu-latest, macOS-latest, windows-latest]
# 32-bit Julia binaries are not available on macOS # 32-bit Julia binaries are not available on macOS
exclude: exclude:
- os: macOS-latest - os: macOS-latest
julia-arch: x86 julia-arch: x86
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v1.0.0
- uses: actions/setup-node@v4
if: ${{ ! startsWith(github.ref, 'refs/heads/releases') }}
with:
node-version-file: '.tool-versions'
- name: "Install dependencies" - name: "Install dependencies"
if: ${{ ! startsWith(github.ref, 'refs/heads/releases') }}
run: | run: |
npm install npm install
npm run build npm run build
@@ -50,5 +36,3 @@ jobs:
arch: ${{ matrix.julia-arch }} arch: ${{ matrix.julia-arch }}
- run: julia --version - run: julia --version
- run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()' - run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'
- name: "Check that the correct julia is used and that archive mtimes are maintained"
run: julia --startup-file=no --color=yes ./.github/scripts/common-tests.jl

View File

@@ -1 +0,0 @@
nodejs 20.11.1

View File

@@ -1,3 +1,11 @@
# Contributing # Dev docs / Contributing guide
Please see the README in the [`devdocs/`](devdocs/) folder. ## Building and tagging a release (requires write access)
1. Test your changes, merge into `master`.
2. Checkout `master`.
3. Bump the version number in [`package.json`](package.json).
4. Run `./bin/build-release julia-actions/setup-julia` to create a release branch and build a release.
5. Push the branch (**without tags**) and verify that CI is passing on it.
6. Run `git push --tags --force` to update the tags.
7. Create a release for the `vX.Y.Z` tag.

123
README.md
View File

@@ -1,6 +1,7 @@
# setup-julia Action # setup-julia Action
[![CodeQL](https://github.com/julia-actions/setup-julia/workflows/CodeQL/badge.svg)](https://securitylab.github.com/tools/codeql) [![CodeQL](https://github.com/julia-actions/setup-julia/workflows/CodeQL/badge.svg)](https://securitylab.github.com/tools/codeql)
[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=julia-actions/setup-julia)](https://dependabot.com)
This action sets up a Julia environment for use in actions by downloading a specified version of Julia and adding it to PATH. This action sets up a Julia environment for use in actions by downloading a specified version of Julia and adding it to PATH.
@@ -22,7 +23,7 @@ This action sets up a Julia environment for use in actions by downloading a spec
### Inputs ### Inputs
```yaml ```yaml
- uses: julia-actions/setup-julia@v2 - uses: julia-actions/setup-julia@v1
with: with:
# The Julia version that will be installed and added as `julia` to the PATH. # The Julia version that will be installed and added as `julia` to the PATH.
# See "Julia Versions" below for a list of valid values. # See "Julia Versions" below for a list of valid values.
@@ -37,15 +38,9 @@ This action sets up a Julia environment for use in actions by downloading a spec
# The architecture of the Julia binaries. # The architecture of the Julia binaries.
# #
# Please note that installing aarch64 binaries only makes sense on self-hosted aarch64 runners. # Supported values: x64 | x86
# We currently don't run test builds on that architecture, so we cannot guarantee that the input won't break randomly,
# although there is no reason why it would.
# #
# Supported values: x64 | x86 | aarch64 (untested) # Default: x64
#
# Note: you can use X64, X86, and ARM64 as synonyms for x64, x86, and aarch64, respectively.
#
# Defaults to the architecture of the runner executing the job.
arch: '' arch: ''
# Set the display setting for printing InteractiveUtils.versioninfo() after installing. # Set the display setting for printing InteractiveUtils.versioninfo() after installing.
@@ -86,10 +81,10 @@ outputs:
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v1.0.0
- uses: julia-actions/setup-julia@v2 - uses: julia-actions/setup-julia@v1
with: with:
version: '1.10' version: 1.0.4
- run: julia -e 'println("Hello, World!")' - run: julia -e 'println("Hello, World!")'
``` ```
@@ -97,53 +92,22 @@ steps:
You can either specify specific Julia versions or version ranges. If you specify a version range, the **highest** available Julia version that matches the range will be selected. You can either specify specific Julia versions or version ranges. If you specify a version range, the **highest** available Julia version that matches the range will be selected.
> **Warning** **Warning:** It is strongly recommended to wrap versions in quotes. Otherwise, the YAML parser used by GitHub Actions parses certain versions as numbers which causes the wrong version to be selected. For example, `1.0` may be parsed as `1`.
>
> It is strongly recommended to wrap versions in quotes. Otherwise, the YAML parser used by GitHub Actions parses certain versions as numbers which causes the wrong version to be selected. For example, `1.0` may be parsed as `1`.
#### Examples #### Examples
- `'1.2.0'` is a valid semver version. The action will try to download exactly this version. If it's not available, the build step will fail. - `1.2.0` is a valid semver version. The action will try to download exactly this version. If it's not available, the build step will fail.
- `'1.0'` is a version range that will match the highest available Julia version that starts with `1.0`, e.g. `1.0.5`, excluding pre-releases. - `1.0` is a version range that will match the highest available Julia version that starts with `1.0`, e.g. `1.0.5`, excluding pre-releases.
- `'^1.3.0-rc1'` is a **caret** version range that includes pre-releases of `1.3.0` starting at `rc1`. It matches all versions `≥ 1.3.0-rc1` and `< 2.0.0`. - `^1.3.0-rc1` is a **caret** version range that includes pre-releases starting at `rc1`. It matches all versions `≥ 1.3.0-rc1` and `< 2.0.0`.
- `'~1.3.0-rc1'` is a **tilde** version range that includes pre-releases of `1.3.0` starting at `rc1`. It matches all versions `≥ 1.3.0-rc1` and `< 1.4.0`. - `~1.3.0-rc1` is a **tilde** version range that includes pre-releases starting at `rc1`. It matches all versions `≥ 1.3.0-rc1` and `< 1.4.0`.
- `'^1.3.0-0'` is a **caret** version range that includes _all_ pre-releases of `1.3.0`. It matches all versions `≥ 1.3.0-` and `< 2.0.0`. - `^1.3.0-0` is a **caret** version range that includes _all_ pre-releases. It matches all versions `≥ 1.3.0-` and `< 2.0.0`.
- `'~1.3.0-0'` is a **tilde** version range that includes _all_ pre-releases of `1.3.0`. It matches all versions `≥ 1.3.0-` and `< 1.4.0`. - `~1.3.0-0` is a **tilde** version range that includes _all_ pre-releases. It matches all versions `≥ 1.3.0-` and `< 1.4.0`.
- `'lts'` will install the latest LTS build. - `nightly` will install the latest nightly build.
- `'pre'` will install the latest prerelease build. - `1.7-nightly` will install the latest nightly build for the upcoming 1.7 release. This version will only be available during certain phases of the Julia release cycle.
- `'nightly'` will install the latest nightly build.
- `'1.7-nightly'` will install the latest nightly build for the upcoming 1.7 release. This version will only be available during certain phases of the Julia release cycle.
Internally the action uses node's semver package to resolve version ranges. Its [documentation](https://github.com/npm/node-semver#advanced-range-syntax) contains more details on the version range syntax. You can test what version will be selected for a given input in this JavaScript [REPL](https://repl.it/@SaschaMann/setup-julia-version-logic). Internally the action uses node's semver package to resolve version ranges. Its [documentation](https://github.com/npm/node-semver#advanced-range-syntax) contains more details on the version range syntax. You can test what version will be selected for a given input in this JavaScript [REPL](https://repl.it/@SaschaMann/setup-julia-version-logic).
#### Prereleases The available Julia versions are pulled from [`versions.json`](https://julialang-s3.julialang.org/bin/versions.json). This file is automatically updated once a day. Therefore it may take up to 24 hours until a newly released Julia version is available in the action.
There are two methods of including pre-releases in version matching:
1. Including the pre-release tag in the version itself, e.g. `'^1.3.0-rc1'`.
2. Setting the input `include-all-prereleases` to `true`.
These behave slightly differently.
1. If the version `a.b.c` contains pre-release tag, all pre-releases of version `a.b.c` will be included in the version matching.
For example, `^1.3.0-rc1` would match `1.3.0-rc2` but would **not** match `1.4.0-rc1` once released.
2. If `include-preleases` is set to true, **all** pre-releases of all versions will be included in the version matching. In this case, `^1.3.0-rc1` would match `1.4.0-rc1` once released.
**Example:** Without `include-all-prereleases: true`, the version `^1.3.0-rc1` would match `1.3.0-rc1`, `1.3.0-rc2`, `1.3.0`, `1.4.0` once they are released.
With `include-all-prereleases: true`, it would match `1.3.0-rc1`, `1.3.0-rc2`, `1.3.0`, `1.4.0-rc1`, `1.4.0`.
If you want to run tests against the latest tagged version, no matter what version that is, you can use
```yaml
- uses: julia-actions/setup-julia@v2
with:
version: '1'
include-all-prereleases: true
```
#### Recently released versions
The available Julia versions are pulled from [`versions.json`](https://julialang-s3.julialang.org/bin/versions.json).
### Matrix Testing ### Matrix Testing
@@ -159,11 +123,11 @@ jobs:
matrix: matrix:
julia-version: ['1.0', '1.2.0', '^1.3.0-rc1'] julia-version: ['1.0', '1.2.0', '^1.3.0-rc1']
os: [ubuntu-latest, windows-latest, macOS-latest] os: [ubuntu-latest, windows-latest, macOS-latest]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v1.0.0
- name: "Set up Julia" - name: "Set up Julia"
uses: julia-actions/setup-julia@v2 uses: julia-actions/setup-julia@v1
with: with:
version: ${{ matrix.julia-version }} version: ${{ matrix.julia-version }}
- run: julia -e 'println("Hello, World!")' - run: julia -e 'println("Hello, World!")'
@@ -185,11 +149,11 @@ jobs:
exclude: exclude:
- os: macOS-latest - os: macOS-latest
julia-arch: x86 julia-arch: x86
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v1.0.0
- name: "Set up Julia" - name: "Set up Julia"
uses: julia-actions/setup-julia@v2 uses: julia-actions/setup-julia@v1
with: with:
version: ${{ matrix.julia-version }} version: ${{ matrix.julia-version }}
arch: ${{ matrix.julia-arch }} arch: ${{ matrix.julia-arch }}
@@ -212,11 +176,11 @@ jobs:
- os: windows-latest - os: windows-latest
julia-version: ['1.0.4'] julia-version: ['1.0.4']
julia-arch: x86 julia-arch: x86
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v1.0.0
- name: "Set up Julia" - name: "Set up Julia"
uses: julia-actions/setup-julia@v2 uses: julia-actions/setup-julia@v1
with: with:
version: ${{ matrix.julia-version }} version: ${{ matrix.julia-version }}
- run: julia -e 'println("Hello, World!")' - run: julia -e 'println("Hello, World!")'
@@ -239,44 +203,23 @@ This action follows [GitHub's advice](https://help.github.com/en/articles/about-
If you don't want to deal with updating the version of the action, similiarly to how Travis CI handles it, use `latest` or major version branches. [Dependabot](https://dependabot.com/) can also be used to automatically create Pull Requests to update actions used in your workflows. If you don't want to deal with updating the version of the action, similiarly to how Travis CI handles it, use `latest` or major version branches. [Dependabot](https://dependabot.com/) can also be used to automatically create Pull Requests to update actions used in your workflows.
It's unlikely, but not impossible, that there will be breaking changes post-v2.0.0 unless a new major version of Julia is introduced. It's unlikely, but not impossible, that there will be breaking changes post-v1.0.0 unless a new major version of Julia is introduced.
You can specify commits, branches or tags in your workflows as follows: You can specify commits, branches or tags in your workflows as follows:
```yaml ```yaml
steps: steps:
- uses: julia-actions/setup-julia@f2258781c657ad9b4b88072c5eeaf9ec8c370874 # commit SHA of the tagged 2.0.0 commit - uses: julia-actions/setup-julia@d3ce119a16594ea9e5d7974813970c73b6ab9e94 # commit SHA of the tagged 1.4.1 commit
- uses: julia-actions/setup-julia@latest # latest version tag (may break existing workflows) - uses: julia-actions/setup-julia@latest # latest version tag (may break existing workflows)
- uses: julia-actions/setup-julia@v2 # major version tag - uses: julia-actions/setup-julia@v1 # major version tag
- uses: julia-actions/setup-julia@v2.0 # minor version tag - uses: julia-actions/setup-julia@v1.4 # minor version tag
- uses: julia-actions/setup-julia@v2.0.0 # specific version tag - uses: julia-actions/setup-julia@v1.4.1 # specific version tag
``` ```
If your workflow requires access to secrets, you should always pin it to a commit SHA instead of a tag. If your workflow requires access to secrets, you should always pin it to a commit SHA instead of a tag.
This will protect you in case a bad actor gains access to the setup-julia repo. This will protect you in case a bad actor gains access to the setup-julia repo.
You can find more information in [GitHub's security hardening guide](https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions). You can find more information in [GitHub's security hardening guide](https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions).
## Using Dependabot version updates to keep your GitHub Actions up to date
We highly recommend that you set up Dependabot version updates on your repo to keep your GitHub Actions up to date.
To set up Dependabot version updates, create a file named `.github/dependabot.yml` in your repo with the following contents:
```yaml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 99
labels:
- "dependencies"
- "github-actions"
```
For more details on Dependabot version updates, see the [GitHub Dependabot documentation](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates).
## Debug logs ## Debug logs
You can enable [Step Debug Logs](https://github.com/actions/toolkit/blob/main/docs/action-debugging.md#step-debug-logs) for more detailed logs. You can enable [Step Debug Logs](https://github.com/actions/toolkit/blob/main/docs/action-debugging.md#step-debug-logs) for more detailed logs.
@@ -285,7 +228,3 @@ Note that when debug logs are enabled, a request will be sent to `https://httpbi
## Third party information ## Third party information
Parts of this software have been derived from other open source software. Parts of this software have been derived from other open source software.
See [THIRD_PARTY_NOTICE.md](THIRD_PARTY_NOTICE.md) for details. See [THIRD_PARTY_NOTICE.md](THIRD_PARTY_NOTICE.md) for details.
## Contributing to this repo
Please see the README in the [`devdocs/`](devdocs/) folder.

File diff suppressed because it is too large Load Diff

View File

@@ -4,30 +4,30 @@
import * as path from 'path' import * as path from 'path'
import * as io from '@actions/io' import * as io from '@actions/io'
import * as semver from 'semver'
import nock = require('nock') import nock = require('nock')
import * as semver from 'semver'
const testVersions = [ const testVersions = [
'0.1.2', '0.1.2', '0.2.0', '0.2.1', '0.3.0',
'0.2.0', '0.2.1', '0.3.1', '0.3.10', '0.3.11', '0.3.12',
'0.3.0', '0.3.1', '0.3.10', '0.3.11', '0.3.12', '0.3.2', '0.3.3', '0.3.4', '0.3.5', '0.3.6', '0.3.7', '0.3.8', '0.3.9', '0.3.2', '0.3.3', '0.3.4', '0.3.5',
'0.4.0', '0.4.0-rc1', '0.4.0-rc2', '0.4.0-rc3', '0.4.0-rc4', '0.4.1', '0.4.2', '0.4.3', '0.4.4', '0.4.5', '0.4.6', '0.4.7', '0.3.6', '0.3.7', '0.3.8', '0.3.9',
'0.5.0', '0.5.0-rc0', '0.5.0-rc1', '0.5.0-rc2', '0.5.0-rc3', '0.5.0-rc4', '0.5.1', '0.5.2', '0.4.0', '0.4.0-rc1', '0.4.0-rc2', '0.4.0-rc3',
'0.6.0', '0.6.0-pre.alpha', '0.6.0-pre.beta', '0.6.0-rc1', '0.6.0-rc2', '0.6.0-rc3', '0.6.1', '0.6.2', '0.6.3', '0.6.4', '0.4.0-rc4', '0.4.1', '0.4.2', '0.4.3',
'0.7.0', '0.7.0-alpha', '0.7.0-beta', '0.7.0-beta2', '0.7.0-rc1', '0.7.0-rc2', '0.7.0-rc3', '0.4.4', '0.4.5', '0.4.6', '0.4.7',
'1.0.0', '1.0.0-rc1', '1.0.1', '1.0.2', '1.0.3', '1.0.4', '1.0.5', '0.5.0', '0.5.0-rc0', '0.5.0-rc1', '0.5.0-rc2',
'1.1.0', '1.1.0-rc1', '1.1.0-rc2', '1.1.1', '0.5.0-rc3', '0.5.0-rc4', '0.5.1', '0.5.2',
'1.2.0', '1.2.0-rc1', '1.2.0-rc2', '1.2.0-rc3', '0.6.0', '0.6.0-pre.alpha', '0.6.0-pre.beta', '0.6.0-rc1',
'1.3.0', '1.3.0-alpha', '1.3.0-rc1', '1.3.0-rc2', '1.3.0-rc3', '1.3.0-rc4', '1.3.0-rc5', '1.3.1', '0.6.0-rc2', '0.6.0-rc3', '0.6.1', '0.6.2',
'1.4.0', '1.4.0-rc1', '1.4.0-rc2', '1.4.1', '1.4.2', '0.6.3', '0.6.4', '0.7.0', '0.7.0-alpha',
'1.5.0', '1.5.0-beta1', '1.5.0-rc1', '1.5.0-rc2', '1.5.1', '1.5.2', '1.5.3', '1.5.4', '0.7.0-beta', '0.7.0-beta2', '0.7.0-rc1', '0.7.0-rc2',
'1.6.0', '1.6.0-beta1', '1.6.0-rc1', '1.6.0-rc2', '1.6.0-rc3', '1.6.1', '1.6.2', '1.6.3', '1.6.4', '1.6.5', '1.6.6', '1.6.7', '0.7.0-rc3', '1.0.0', '1.0.0-rc1', '1.0.1',
'1.7.0', '1.7.0-beta1', '1.7.0-beta2', '1.7.0-beta3', '1.7.0-beta4', '1.7.0-rc1', '1.7.0-rc2', '1.7.0-rc3', '1.7.1', '1.7.2', '1.7.3', '1.0.2', '1.0.3', '1.0.4', '1.0.5',
'1.8.0', '1.8.0-beta1', '1.8.0-beta2', '1.8.0-beta3', '1.8.0-rc1', '1.8.0-rc2', '1.8.0-rc3', '1.8.0-rc4', '1.8.1', '1.8.2', '1.8.3', '1.8.4', '1.8.5', '1.1.0', '1.1.0-rc1', '1.1.0-rc2', '1.1.1',
'1.9.0', '1.9.0-alpha1', '1.9.0-beta1', '1.9.0-beta2', '1.9.0-beta3', '1.9.0-beta4', '1.9.0-rc1', '1.9.0-rc2', '1.9.0-rc3', '1.9.1', '1.9.2', '1.9.3', '1.9.4', '1.2.0', '1.2.0-rc1', '1.2.0-rc2', '1.2.0-rc3',
'1.10.0', '1.10.0-alpha1', '1.10.0-beta1', '1.10.0-beta2', '1.10.0-beta3', '1.10.0-rc1', '1.10.0-rc2', '1.10.0-rc3', '1.10.1', '1.10.2', '1.3.0-alpha', '1.3.0-rc1', '1.3.0-rc2', '1.3.0-rc3',
'1.11.0-alpha1', '1.11.0-alpha2', '1.11.0-beta1' '1.3.0-rc4'
] ]
const toolDir = path.join(__dirname, 'runner', 'tools') const toolDir = path.join(__dirname, 'runner', 'tools')
@@ -55,33 +55,14 @@ describe('version matching tests', () => {
expect(installer.getJuliaVersion([], 'nightly')).toEqual('nightly') expect(installer.getJuliaVersion([], 'nightly')).toEqual('nightly')
expect(installer.getJuliaVersion(testVersions, 'nightly')).toEqual('nightly') expect(installer.getJuliaVersion(testVersions, 'nightly')).toEqual('nightly')
}) })
it('LTS', () => {
// Update test when LTS is updated
expect(installer.getJuliaVersion(testVersions, 'lts')).toEqual(installer.getJuliaVersion(testVersions, '1.6'))
expect(installer.getJuliaVersion(testVersions, 'lts')).toEqual('1.6.7')
})
it('pre', () => {
expect(installer.getJuliaVersion(testVersions, 'pre')).toEqual('1.11.0-beta1')
})
}) })
describe('version ranges', () => { describe('version ranges', () => {
it('Chooses the highest available version that matches the input', () => { it('Chooses the highest available version that matches the input', () => {
expect(installer.getJuliaVersion(testVersions, '1')).toEqual('1.10.2') expect(installer.getJuliaVersion(testVersions, '1')).toEqual('1.2.0')
expect(installer.getJuliaVersion(testVersions, '1.0')).toEqual('1.0.5') expect(installer.getJuliaVersion(testVersions, '1.0')).toEqual('1.0.5')
expect(installer.getJuliaVersion(testVersions, '^1.3.0-rc1')).toEqual('1.10.2') expect(installer.getJuliaVersion(testVersions, '^1.3.0-rc1')).toEqual('1.3.0-rc4')
expect(installer.getJuliaVersion(testVersions, '^1.2.0-rc1')).toEqual('1.10.2') expect(installer.getJuliaVersion(testVersions, '^1.2.0-rc1')).toEqual('1.2.0')
expect(installer.getJuliaVersion(testVersions, '^1.10.0-rc1')).toEqual('1.10.2')
})
})
describe('include-prereleases', () => {
it('Chooses the highest available version that matches the input including prereleases', () => {
expect(installer.getJuliaVersion(testVersions, '^1.2.0-0', true)).toEqual('1.11.0-beta1')
expect(installer.getJuliaVersion(testVersions, '1', true)).toEqual('1.11.0-beta1')
expect(installer.getJuliaVersion(testVersions, '^1.2.0-0', false)).toEqual('1.10.2')
}) })
}) })

View File

@@ -5,14 +5,10 @@ inputs:
version: version:
description: 'The Julia version to download (if necessary) and use. Example: 1.0.4' description: 'The Julia version to download (if necessary) and use. Example: 1.0.4'
default: '1' default: '1'
include-all-prereleases:
description: 'Include prereleases when matching the Julia version to available versions.'
required: false
default: 'false'
arch: arch:
description: 'Architecture of the Julia binaries. Defaults to the architecture of the runner executing the job.' description: 'Architecture of the Julia binaries. Defaults to x64.'
required: false required: false
default: '${{ runner.arch }}' default: 'x64'
show-versioninfo: show-versioninfo:
description: 'Display InteractiveUtils.versioninfo() after installing' description: 'Display InteractiveUtils.versioninfo() after installing'
required: false required: false
@@ -23,7 +19,7 @@ outputs:
julia-bindir: julia-bindir:
description: 'Path to the directory containing the Julia executable. Equivalent to JULIA_BINDIR: https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_BINDIR' description: 'Path to the directory containing the Julia executable. Equivalent to JULIA_BINDIR: https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_BINDIR'
runs: runs:
using: 'node20' using: 'node12'
main: 'dist/index.js' main: 'dist/index.js'
branding: branding:
icon: 'download' icon: 'download'

View File

@@ -1,7 +0,0 @@
# Devdocs for the `setup-julia` repo
If you want to make a pull request to this repo, please read the following:
1. [Local development](local_setup.md)
If you have commit access to this repo, you may be interested in the following:
1. [Making a new release of this action](making_a_new_release.md)

View File

@@ -1,47 +0,0 @@
# Local development
## 1. Clone the repo
```bash
git clone git@github.com:julia-actions/setup-julia.git
cd setup-julia
```
## 2. Install NodeJS
### Unix, using `asdf` (recommended, but not required)
First, make sure that you have installed [`asdf`](https://asdf-vm.com/) on your local machine.
Then, `cd` to your clone of the repo and run the following commands:
```bash
asdf plugin add nodejs
asdf install
```
This will use `asdf` to install the correct version of NodeJS.
### Unix, but not using `asdf`
Instead of using `asdf`, you can instead choose to install NodeJS manually.
First, check the `.tool-versions` file in this repo, and see what version of NodeJS you need. Then, install that same version of NodejS on your local machine.
### Windows
`asdf` does not (currently) support Windows. So on Windows, you have to install NodeJS manually.
First, check the `.tool-versions` file in this repo, and see what version of NodeJS you need. Then, install that same version of NodejS on your local machine.
## 3. Working locally
First, `cd` to your clone of the repo. Now you can run the following commands:
```bash
npm ci
npm run build
```
When you are ready, you can commit your changes and push them to your PR.

View File

@@ -1,128 +0,0 @@
# Making a new release of this action (requires commit access)
If you have commit access to this repo, you can make a new release.
Here are the instructions.
## Step 1: Clone a fresh copy of the repo
We intentionally work in a brand-new copy of the repo.
```bash
git clone git@github.com:julia-actions/setup-julia.git
cd setup-julia
git checkout master
git submodule init
git submodule update
```
## Step 2: Make sure you have the right version of NodeJS
If you use [`asdf`](https://asdf-vm.com/), this is as simple as:
```bash
asdf plugin add nodejs
asdf install
```
If you don't use `asdf`, then you need to:
1. Open the `./tool-versions` file in the root of the repo.
2. Make note of the NodeJS version listed in the `.tool-versions` file.
3. Install that same version of NodeJS on your machine.
4. Make sure that you are currently using that version of NodeJS (i.e. it is at the front of your PATH).
## Step 3: Edit the `version` field in `package.json`
```bash
vim package.json
# Edit the `version` number (should be line 2)
# Save your changes in Vim. Then exit Vim.
# For the remaining of this guide, let MAJOR.MINOR.PATCH refer
# to the new version number that you set.
git add package.json
# No need to commit yet.
# The release script will run `git commit`.
```
## Step 4: Remove the `dist/` line from the `.gitignore` file
```bash
vim .gitignore
# Delete the line that says `dist/` (it should be line 3)
# Save your changes in Vim. Then exit Vim.
git add .gitignore
# No need to commit yet.
# The release script will run `git commit`.
```
## Step 5: Make sure you have the necessary dependencies
The `build-release.sh` script requires the following dependencies:
1. Bash
2. `curl`
3. `git`
4. `jq`
5. `sed`
## Step 6: Run the `build-release.sh` script
```bash
ls -l bin/build-release.sh
chmod +x bin/build-release.sh
ls -l bin/build-release.sh
./bin/build-release.sh julia-actions/setup-julia
```
Wait a minute or two. The script will build everything and will create a new release branch named `releases/vMAJOR.MINOR.PATCH`.
## Step 7: Push ONLY the `releases/vMAJOR.MINOR.PATCH` branch
Only push the `releases/` branch. Do NOT push any tags yet.
```bash
git push origin releases/vMAJOR.MINOR.PATCH
```
Now you need to go to https://github.com/julia-actions/setup-julia/tree/releases/vMAJOR.MINOR.PATCH and wait for CI to finish running.
Do NOT proceed to the next step until CI is all green on the `releases/vMAJOR.MINOR.PATCH` branch.
## Step 8: Push the tags (only after CI is all green)
Once CI is all green on the `releases/vMAJOR.MINOR.PATCH` branch, you can push the tags.
You need to force-push.
```bash
git push --tags --force
```
## Step 9: Use the GitHub web UI to create a new GitHub Release
Go to https://github.com/julia-actions/setup-julia/releases and create a new release for the now-existant `vMAJOR.MINOR.PATCH` tag using the GitHub web interface.
## Step 10: Clean up your local repo
```bash
git submodule deinit --force .
git submodule update --init
git fetch --all --prune
git checkout master
git reset --hard origin/master
```
## Step 11: Delete your local repo
```bash
cd ..
ls setup-julia
rm -rf setup-julia
```

10182
dist/index.js vendored

File diff suppressed because it is too large Load Diff

BIN
dist/unzip vendored Normal file

Binary file not shown.

View File

@@ -1,4 +1,4 @@
# Misc notes for contributors # Contributors
### Checkin ### Checkin
@@ -19,4 +19,4 @@ git commit -m "Informative commit message" # Commit. This will run Husky
``` ```
During the commit step, Husky will take care of formatting all files with [Prettier](https://github.com/prettier/prettier) as well as pruning out devDependencies using `npm prune --production`. During the commit step, Husky will take care of formatting all files with [Prettier](https://github.com/prettier/prettier) as well as pruning out devDependencies using `npm prune --production`.
It will also make sure these changes are appropriately included in your commit (no further work is needed) It will also make sure these changes are appropriately included in your commit (no further work is needed)

183
lib/installer.js generated
View File

@@ -1,38 +1,20 @@
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) { return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next()); step((generator = generator.apply(thisArg, _arguments || [])).next());
}); });
}; };
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.showVersionInfo = exports.installJulia = exports.getDownloadURL = exports.getFileInfo = exports.getJuliaVersion = exports.getJuliaVersions = exports.getJuliaVersionInfo = void 0;
const core = __importStar(require("@actions/core")); const core = __importStar(require("@actions/core"));
const exec = __importStar(require("@actions/exec")); const exec = __importStar(require("@actions/exec"));
const tc = __importStar(require("@actions/tool-cache")); const tc = __importStar(require("@actions/tool-cache"));
@@ -42,8 +24,6 @@ const os = __importStar(require("os"));
const path = __importStar(require("path")); const path = __importStar(require("path"));
const retry = require("async-retry"); const retry = require("async-retry");
const semver = __importStar(require("semver")); const semver = __importStar(require("semver"));
const LTS_VERSION = '1.6';
const MAJOR_VERSION = '1'; // Could be deduced from versions.json
// Translations between actions input and Julia arch names // Translations between actions input and Julia arch names
const osMap = { const osMap = {
'win32': 'winnt', 'win32': 'winnt',
@@ -52,8 +32,7 @@ const osMap = {
}; };
const archMap = { const archMap = {
'x86': 'i686', 'x86': 'i686',
'x64': 'x86_64', 'x64': 'x86_64'
'aarch64': 'aarch64'
}; };
// Store information about the environment // Store information about the environment
const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS) const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS)
@@ -86,9 +65,8 @@ function getJuliaVersionInfo() {
const versionsFile = yield retry((bail) => __awaiter(this, void 0, void 0, function* () { const versionsFile = yield retry((bail) => __awaiter(this, void 0, void 0, function* () {
return yield tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json'); return yield tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json');
}), { }), {
retries: 5,
onRetry: (err) => { onRetry: (err) => {
core.info(`Download of versions.json failed, trying again. Error: ${err}`); core.debug(`Download of versions.json failed, trying again. Error: ${err}`);
} }
}); });
return JSON.parse(fs.readFileSync(versionsFile).toString()); return JSON.parse(fs.readFileSync(versionsFile).toString());
@@ -108,19 +86,13 @@ function getJuliaVersions(versionInfo) {
}); });
} }
exports.getJuliaVersions = getJuliaVersions; exports.getJuliaVersions = getJuliaVersions;
function getJuliaVersion(availableReleases, versionInput, includePrerelease = false) { function getJuliaVersion(availableReleases, versionInput) {
if (semver.valid(versionInput) == versionInput || versionInput.endsWith('nightly')) { if (semver.valid(versionInput) == versionInput || versionInput.endsWith('nightly')) {
// versionInput is a valid version or a nightly version, use it directly // versionInput is a valid version or a nightly version, use it directly
return versionInput; return versionInput;
} }
if (versionInput == 'lts') {
return getJuliaVersion(availableReleases, LTS_VERSION, false);
}
if (versionInput == 'pre') {
return getJuliaVersion(availableReleases, MAJOR_VERSION, true);
}
// Use the highest available version that matches versionInput // Use the highest available version that matches versionInput
let version = semver.maxSatisfying(availableReleases, versionInput, { includePrerelease }); let version = semver.maxSatisfying(availableReleases, versionInput);
if (version == null) { if (version == null) {
throw new Error(`Could not find a Julia version that matches ${versionInput}`); throw new Error(`Could not find a Julia version that matches ${versionInput}`);
} }
@@ -129,87 +101,30 @@ function getJuliaVersion(availableReleases, versionInput, includePrerelease = fa
return version; return version;
} }
exports.getJuliaVersion = getJuliaVersion; exports.getJuliaVersion = getJuliaVersion;
function getDesiredFileExts() {
let fileExt1;
let hasFileExt2;
let fileExt2;
if (osPlat == 'win32') {
fileExt1 = 'tar.gz';
hasFileExt2 = true;
fileExt2 = 'exe';
}
else if (osPlat == 'darwin') {
fileExt1 = 'tar.gz';
hasFileExt2 = true;
fileExt2 = 'dmg';
}
else if (osPlat === 'linux') {
fileExt1 = 'tar.gz';
hasFileExt2 = false;
fileExt2 = '';
}
else {
throw new Error(`Platform ${osPlat} is not supported`);
}
return [fileExt1, hasFileExt2, fileExt2];
}
function getNightlyFileName(arch) { function getNightlyFileName(arch) {
let versionExt; let versionExt, ext;
let fileExt1;
[fileExt1, ,] = getDesiredFileExts();
if (osPlat == 'win32') { if (osPlat == 'win32') {
if (arch == 'x86') { versionExt = arch == 'x64' ? '-win64' : '-win32';
versionExt = '-win32'; ext = 'exe';
}
else if (arch == 'aarch64') {
throw new Error('Aarch64 Julia is not available on Windows');
}
else if (arch == 'x64') {
versionExt = '-win64';
}
else {
throw new Error(`Architecture ${arch} is not supported on Windows`);
}
} }
else if (osPlat == 'darwin') { else if (osPlat == 'darwin') {
if (arch == 'x86') { if (arch == 'x86') {
throw new Error('32-bit (x86) Julia is not available on macOS'); throw new Error('32-bit Julia is not available on macOS');
}
else if (arch == 'aarch64') {
versionExt = '-macaarch64';
}
else if (arch == 'x64') {
versionExt = '-mac64';
}
else {
throw new Error(`Architecture ${arch} is not supported on macOS`);
} }
versionExt = '-mac64';
ext = 'dmg';
} }
else if (osPlat === 'linux') { else if (osPlat === 'linux') {
if (arch == 'x86') { versionExt = arch == 'x64' ? '-linux64' : '-linux32';
versionExt = '-linux32'; ext = 'tar.gz';
}
else if (arch == 'aarch64') {
versionExt = '-linux-aarch64';
}
else if (arch == 'x64') {
versionExt = '-linux64';
}
else {
throw new Error(`Architecture ${arch} is not supported on Linux`);
}
} }
else { else {
throw new Error(`Platform ${osPlat} is not supported`); throw new Error(`Platform ${osPlat} is not supported`);
} }
return `julia-latest${versionExt}.${fileExt1}`; return `julia-latest${versionExt}.${ext}`;
} }
function getFileInfo(versionInfo, version, arch) { function getFileInfo(versionInfo, version, arch) {
const err = `Could not find ${archMap[arch]}/${version} binaries`; const err = `Could not find ${archMap[arch]}/${version} binaries`;
let fileExt1;
let hasFileExt2;
let fileExt2;
[fileExt1, hasFileExt2, fileExt2] = getDesiredFileExts();
if (version.endsWith('nightly')) { if (version.endsWith('nightly')) {
return null; return null;
} }
@@ -218,19 +133,7 @@ function getFileInfo(versionInfo, version, arch) {
} }
for (let file of versionInfo[version].files) { for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) { if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
if (file.extension == fileExt1) { return file;
return file;
}
}
}
if (hasFileExt2) {
core.debug(`Could not find ${fileExt1}; trying to find ${fileExt2} instead`);
for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
if (file.extension == fileExt2) {
return file;
}
}
} }
} }
throw err; throw err;
@@ -254,7 +157,7 @@ function getDownloadURL(fileInfo, version, arch) {
return fileInfo.url; return fileInfo.url;
} }
exports.getDownloadURL = getDownloadURL; exports.getDownloadURL = getDownloadURL;
function installJulia(dest, versionInfo, version, arch) { function installJulia(versionInfo, version, arch) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
// Download Julia // Download Julia
const fileInfo = getFileInfo(versionInfo, version, arch); const fileInfo = getFileInfo(versionInfo, version, arch);
@@ -265,9 +168,8 @@ function installJulia(dest, versionInfo, version, arch) {
const juliaDownloadPath = yield retry((bail) => __awaiter(this, void 0, void 0, function* () { const juliaDownloadPath = yield retry((bail) => __awaiter(this, void 0, void 0, function* () {
return yield tc.downloadTool(downloadURL); return yield tc.downloadTool(downloadURL);
}), { }), {
retries: 5,
onRetry: (err) => { onRetry: (err) => {
core.info(`Download of ${downloadURL} failed, trying again. Error: ${err}`); core.debug(`Download of ${downloadURL} failed, trying again. Error: ${err}`);
} }
}); });
// Verify checksum // Verify checksum
@@ -281,41 +183,26 @@ function installJulia(dest, versionInfo, version, arch) {
else { else {
core.debug('Skipping checksum check for nightly binaries.'); core.debug('Skipping checksum check for nightly binaries.');
} }
const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`);
// Install it // Install it
switch (osPlat) { switch (osPlat) {
case 'linux': case 'linux':
// tc.extractTar doesn't support stripping components, so we have to call tar manually // tc.extractTar doesn't support stripping components, so we have to call tar manually
yield exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', dest]); yield exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', tempInstallDir]);
return dest; return tempInstallDir;
case 'win32': case 'win32':
if (fileInfo !== null && fileInfo.extension == 'exe') { if (version.endsWith('nightly') || semver.gtr(version, '1.3', { includePrerelease: true })) {
if (version.endsWith('nightly') || semver.gtr(version, '1.3', { includePrerelease: true })) { // The installer changed in 1.4: https://github.com/JuliaLang/julia/blob/ef0c9108b12f3ae177c51037934351ffa703b0b5/NEWS.md#build-system-changes
// The installer changed in 1.4: https://github.com/JuliaLang/julia/blob/ef0c9108b12f3ae177c51037934351ffa703b0b5/NEWS.md#build-system-changes yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`]);
yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${path.join(process.cwd(), dest)}" -NoNewWindow -Wait`]);
}
else {
yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${path.join(process.cwd(), dest)}" -NoNewWindow -Wait`]);
}
} }
else { else {
// This is the more common path. Using .tar.gz is much faster yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`]);
// don't use the Git bash provided tar. Issue #205
// https://github.com/julia-actions/setup-julia/issues/205
yield exec.exec('powershell', ['-Command', `& "$env:WINDIR/System32/tar" xf ${juliaDownloadPath} --strip-components=1 -C ${dest}`]);
} }
return dest; return tempInstallDir;
case 'darwin': case 'darwin':
if (fileInfo !== null && fileInfo.extension == 'dmg') { yield exec.exec('hdiutil', ['attach', juliaDownloadPath]);
core.debug(`Support for .dmg files is deprecated and may be removed in a future release`); yield exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${tempInstallDir}`]);
yield exec.exec('hdiutil', ['attach', juliaDownloadPath]); return path.join(tempInstallDir, 'julia');
yield exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${dest}`]);
return path.join(dest, 'julia');
}
else {
// tc.extractTar doesn't support stripping components, so we have to call tar manually
yield exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', dest]);
return dest;
}
default: default:
throw new Error(`Platform ${osPlat} is not supported`); throw new Error(`Platform ${osPlat} is not supported`);
} }

66
lib/setup-julia.js generated
View File

@@ -1,36 +1,19 @@
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) { return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next()); step((generator = generator.apply(thisArg, _arguments || [])).next());
}); });
}; };
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core")); const core = __importStar(require("@actions/core"));
const tc = __importStar(require("@actions/tool-cache")); const tc = __importStar(require("@actions/tool-cache"));
@@ -38,15 +21,6 @@ const fs = __importStar(require("fs"));
const https = __importStar(require("https")); const https = __importStar(require("https"));
const path = __importStar(require("path")); const path = __importStar(require("path"));
const installer = __importStar(require("./installer")); const installer = __importStar(require("./installer"));
const archSynonyms = {
'x86': 'x86',
'X86': 'x86',
'x64': 'x64',
'X64': 'x64',
'aarch64': 'aarch64',
'ARM64': 'aarch64',
'arm64': 'aarch64'
};
function run() { function run() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
@@ -67,8 +41,7 @@ function run() {
} }
// Inputs // Inputs
const versionInput = core.getInput('version'); const versionInput = core.getInput('version');
const includePrereleases = core.getInput('include-all-prereleases') == 'true'; const arch = core.getInput('arch');
const originalArchInput = core.getInput('arch');
// It can easily happen that, for example, a workflow file contains an input `version: ${{ matrix.julia-version }}` // It can easily happen that, for example, a workflow file contains an input `version: ${{ matrix.julia-version }}`
// while the strategy matrix only contains a key `${{ matrix.version }}`. // while the strategy matrix only contains a key `${{ matrix.version }}`.
// In that case, we want the action to fail, rather than trying to download julia from an URL that's missing parts and 404ing. // In that case, we want the action to fail, rather than trying to download julia from an URL that's missing parts and 404ing.
@@ -77,13 +50,12 @@ function run() {
if (!versionInput) { if (!versionInput) {
throw new Error('Version input must not be null'); throw new Error('Version input must not be null');
} }
if (!originalArchInput) { if (!arch) {
throw new Error(`Arch input must not be null`); throw new Error(`Arch input must not be null`);
} }
const arch = archSynonyms[originalArchInput];
const versionInfo = yield installer.getJuliaVersionInfo(); const versionInfo = yield installer.getJuliaVersionInfo();
const availableReleases = yield installer.getJuliaVersions(versionInfo); const availableReleases = yield installer.getJuliaVersions(versionInfo);
const version = installer.getJuliaVersion(availableReleases, versionInput, includePrereleases); const version = installer.getJuliaVersion(availableReleases, versionInput);
core.debug(`selected Julia version: ${arch}/${version}`); core.debug(`selected Julia version: ${arch}/${version}`);
core.setOutput('julia-version', version); core.setOutput('julia-version', version);
// Search in cache // Search in cache
@@ -91,18 +63,12 @@ function run() {
juliaPath = tc.find('julia', version, arch); juliaPath = tc.find('julia', version, arch);
if (!juliaPath) { if (!juliaPath) {
core.debug(`could not find Julia ${arch}/${version} in cache`); core.debug(`could not find Julia ${arch}/${version} in cache`);
// https://github.com/julia-actions/setup-julia/pull/196 const juliaInstallationPath = yield installer.installJulia(versionInfo, version, arch);
// we want julia to be installed with unmodified file mtimes // Add it to cache
// but `tc.cacheDir` uses `cp` internally which destroys mtime juliaPath = yield tc.cacheDir(juliaInstallationPath, 'julia', version, arch);
// and `tc` provides no API to get the tool directory alone
// so hack it by installing a empty directory then use the path it returns
// and extract the archives directly to that location
const emptyDir = fs.mkdtempSync('empty');
juliaPath = yield tc.cacheDir(emptyDir, 'julia', version, arch);
yield installer.installJulia(juliaPath, versionInfo, version, arch);
core.debug(`added Julia to cache: ${juliaPath}`); core.debug(`added Julia to cache: ${juliaPath}`);
// Remove empty dir // Remove temporary dir
fs.rmdirSync(emptyDir); fs.rmdirSync(juliaInstallationPath, { recursive: true });
} }
else { else {
core.debug(`using cached version of Julia: ${juliaPath}`); core.debug(`using cached version of Julia: ${juliaPath}`);

13424
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "setup-julia", "name": "setup-julia",
"version": "2.2.0", "version": "1.6.1",
"private": true, "private": true,
"description": "setup Julia action", "description": "setup Julia action",
"main": "lib/setup-julia.js", "main": "lib/setup-julia.js",
@@ -21,25 +21,24 @@
"author": "Sascha Mann <git@mail.saschamann.eu>", "author": "Sascha Mann <git@mail.saschamann.eu>",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.10.1", "@actions/core": "^1.2.6",
"@actions/exec": "^1.1.1", "@actions/exec": "^1.0.0",
"@actions/io": "^1.1.3", "@actions/io": "^1.0.0",
"@actions/tool-cache": "^2.0.1", "@actions/tool-cache": "^1.0.0",
"async-retry": "^1.3.3", "async-retry": "^1.3.1",
"semver": "^7.6.2" "semver": "^6.3.0"
}, },
"devDependencies": { "devDependencies": {
"@types/async-retry": "^1.4.8", "@types/async-retry": "^1.4.2",
"@types/jest": "^29.5.12", "@types/jest": "^24.0.13",
"@types/node": "^20.14.6", "@types/node": "^12.12.7",
"@types/retry": "^0.12.5", "@types/semver": "^6.0.0",
"@types/semver": "^7.5.8", "@zeit/ncc": "^0.22.0",
"@vercel/ncc": "^0.38.1", "jest": "^24.8.0",
"jest": "^29.7.0", "jest-circus": "^24.7.1",
"jest-circus": "^29.7.0", "nock": "^11.7.2",
"nock": "^13.5.4", "prettier": "^1.17.1",
"prettier": "^3.3.2", "ts-jest": "^26.0.0",
"ts-jest": "^29.1.5", "typescript": "^3.5.1"
"typescript": "^5.4.5"
} }
} }

View File

@@ -10,9 +10,6 @@ import retry = require('async-retry')
import * as semver from 'semver' import * as semver from 'semver'
const LTS_VERSION = '1.6'
const MAJOR_VERSION = '1' // Could be deduced from versions.json
// Translations between actions input and Julia arch names // Translations between actions input and Julia arch names
const osMap = { const osMap = {
'win32': 'winnt', 'win32': 'winnt',
@@ -21,8 +18,7 @@ const osMap = {
} }
const archMap = { const archMap = {
'x86': 'i686', 'x86': 'i686',
'x64': 'x86_64', 'x64': 'x86_64'
'aarch64': 'aarch64'
} }
// Store information about the environment // Store information about the environment
@@ -57,9 +53,8 @@ export async function getJuliaVersionInfo(): Promise<object> {
const versionsFile = await retry(async (bail: Function) => { const versionsFile = await retry(async (bail: Function) => {
return await tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json') return await tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json')
}, { }, {
retries: 5,
onRetry: (err: Error) => { onRetry: (err: Error) => {
core.info(`Download of versions.json failed, trying again. Error: ${err}`) core.debug(`Download of versions.json failed, trying again. Error: ${err}`)
} }
}) })
@@ -79,22 +74,14 @@ export async function getJuliaVersions(versionInfo): Promise<string[]> {
return versions return versions
} }
export function getJuliaVersion(availableReleases: string[], versionInput: string, includePrerelease: boolean = false): string { export function getJuliaVersion(availableReleases: string[], versionInput: string): string {
if (semver.valid(versionInput) == versionInput || versionInput.endsWith('nightly')) { if (semver.valid(versionInput) == versionInput || versionInput.endsWith('nightly')) {
// versionInput is a valid version or a nightly version, use it directly // versionInput is a valid version or a nightly version, use it directly
return versionInput return versionInput
} }
if (versionInput == 'lts') {
return getJuliaVersion(availableReleases, LTS_VERSION, false)
}
if (versionInput == 'pre') {
return getJuliaVersion(availableReleases, MAJOR_VERSION, true)
}
// Use the highest available version that matches versionInput // Use the highest available version that matches versionInput
let version = semver.maxSatisfying(availableReleases, versionInput, {includePrerelease}) let version = semver.maxSatisfying(availableReleases, versionInput)
if (version == null) { if (version == null) {
throw new Error(`Could not find a Julia version that matches ${versionInput}`) throw new Error(`Could not find a Julia version that matches ${versionInput}`)
} }
@@ -105,80 +92,31 @@ export function getJuliaVersion(availableReleases: string[], versionInput: strin
return version return version
} }
function getDesiredFileExts(): [string, boolean, string] {
let fileExt1: string
let hasFileExt2: boolean
let fileExt2: string
if (osPlat == 'win32') {
fileExt1 = 'tar.gz'
hasFileExt2 = true
fileExt2 = 'exe'
} else if (osPlat == 'darwin') {
fileExt1 = 'tar.gz'
hasFileExt2 = true
fileExt2 = 'dmg'
} else if (osPlat === 'linux') {
fileExt1 = 'tar.gz'
hasFileExt2 = false
fileExt2 = ''
} else {
throw new Error(`Platform ${osPlat} is not supported`)
}
return [fileExt1, hasFileExt2, fileExt2]
}
function getNightlyFileName(arch: string): string { function getNightlyFileName(arch: string): string {
let versionExt: string let versionExt: string, ext: string
let fileExt1: string
[fileExt1, , ] = getDesiredFileExts()
if (osPlat == 'win32') { if (osPlat == 'win32') {
if (arch == 'x86') { versionExt = arch == 'x64' ? '-win64' : '-win32'
versionExt = '-win32' ext = 'exe'
} else if (arch == 'aarch64') {
throw new Error('Aarch64 Julia is not available on Windows')
} else if (arch == 'x64') {
versionExt = '-win64'
} else {
throw new Error(`Architecture ${arch} is not supported on Windows`)
}
} else if (osPlat == 'darwin') { } else if (osPlat == 'darwin') {
if (arch == 'x86') { if (arch == 'x86') {
throw new Error('32-bit (x86) Julia is not available on macOS') throw new Error('32-bit Julia is not available on macOS')
} else if (arch == 'aarch64') {
versionExt = '-macaarch64'
} else if (arch == 'x64') {
versionExt = '-mac64'
} else {
throw new Error(`Architecture ${arch} is not supported on macOS`)
} }
versionExt = '-mac64'
ext = 'dmg'
} else if (osPlat === 'linux') { } else if (osPlat === 'linux') {
if (arch == 'x86') { versionExt = arch == 'x64' ? '-linux64' : '-linux32'
versionExt = '-linux32' ext = 'tar.gz'
} else if (arch == 'aarch64') {
versionExt = '-linux-aarch64'
} else if (arch == 'x64') {
versionExt = '-linux64'
} else {
throw new Error(`Architecture ${arch} is not supported on Linux`)
}
} else { } else {
throw new Error(`Platform ${osPlat} is not supported`) throw new Error(`Platform ${osPlat} is not supported`)
} }
return `julia-latest${versionExt}.${fileExt1}` return `julia-latest${versionExt}.${ext}`
} }
export function getFileInfo(versionInfo, version: string, arch: string) { export function getFileInfo(versionInfo, version: string, arch: string) {
const err = `Could not find ${archMap[arch]}/${version} binaries` const err = `Could not find ${archMap[arch]}/${version} binaries`
let fileExt1: string
let hasFileExt2: boolean
let fileExt2: string
[fileExt1, hasFileExt2, fileExt2] = getDesiredFileExts()
if (version.endsWith('nightly')) { if (version.endsWith('nightly')) {
return null return null
} }
@@ -189,20 +127,7 @@ export function getFileInfo(versionInfo, version: string, arch: string) {
for (let file of versionInfo[version].files) { for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) { if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
if (file.extension == fileExt1) { return file
return file
}
}
}
if (hasFileExt2) {
core.debug(`Could not find ${fileExt1}; trying to find ${fileExt2} instead`)
for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
if (file.extension == fileExt2) {
return file
}
}
} }
} }
@@ -230,7 +155,7 @@ export function getDownloadURL(fileInfo, version: string, arch: string): string
return fileInfo.url return fileInfo.url
} }
export async function installJulia(dest: string, versionInfo, version: string, arch: string): Promise<string> { export async function installJulia(versionInfo, version: string, arch: string): Promise<string> {
// Download Julia // Download Julia
const fileInfo = getFileInfo(versionInfo, version, arch) const fileInfo = getFileInfo(versionInfo, version, arch)
const downloadURL = getDownloadURL(fileInfo, version, arch) const downloadURL = getDownloadURL(fileInfo, version, arch)
@@ -241,12 +166,12 @@ export async function installJulia(dest: string, versionInfo, version: string, a
const juliaDownloadPath = await retry(async (bail: Function) => { const juliaDownloadPath = await retry(async (bail: Function) => {
return await tc.downloadTool(downloadURL) return await tc.downloadTool(downloadURL)
}, { }, {
retries: 5,
onRetry: (err: Error) => { onRetry: (err: Error) => {
core.info(`Download of ${downloadURL} failed, trying again. Error: ${err}`) core.debug(`Download of ${downloadURL} failed, trying again. Error: ${err}`)
} }
}) })
// Verify checksum // Verify checksum
if (!version.endsWith('nightly')) { if (!version.endsWith('nightly')) {
const checkSum = await calculateChecksum(juliaDownloadPath) const checkSum = await calculateChecksum(juliaDownloadPath)
@@ -258,38 +183,26 @@ export async function installJulia(dest: string, versionInfo, version: string, a
core.debug('Skipping checksum check for nightly binaries.') core.debug('Skipping checksum check for nightly binaries.')
} }
const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`)
// Install it // Install it
switch (osPlat) { switch (osPlat) {
case 'linux': case 'linux':
// tc.extractTar doesn't support stripping components, so we have to call tar manually // tc.extractTar doesn't support stripping components, so we have to call tar manually
await exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', dest]) await exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', tempInstallDir])
return dest return tempInstallDir
case 'win32': case 'win32':
if (fileInfo !== null && fileInfo.extension == 'exe') { if (version.endsWith('nightly') || semver.gtr(version, '1.3', {includePrerelease: true})) {
if (version.endsWith('nightly') || semver.gtr(version, '1.3', {includePrerelease: true})) { // The installer changed in 1.4: https://github.com/JuliaLang/julia/blob/ef0c9108b12f3ae177c51037934351ffa703b0b5/NEWS.md#build-system-changes
// The installer changed in 1.4: https://github.com/JuliaLang/julia/blob/ef0c9108b12f3ae177c51037934351ffa703b0b5/NEWS.md#build-system-changes await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`])
await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${path.join(process.cwd(), dest)}" -NoNewWindow -Wait`])
} else {
await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${path.join(process.cwd(), dest)}" -NoNewWindow -Wait`])
}
} else { } else {
// This is the more common path. Using .tar.gz is much faster await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`])
// don't use the Git bash provided tar. Issue #205
// https://github.com/julia-actions/setup-julia/issues/205
await exec.exec('powershell', ['-Command', `& "$env:WINDIR/System32/tar" xf ${juliaDownloadPath} --strip-components=1 -C ${dest}`])
} }
return dest return tempInstallDir
case 'darwin': case 'darwin':
if (fileInfo !== null && fileInfo.extension == 'dmg') { await exec.exec('hdiutil', ['attach', juliaDownloadPath])
core.debug(`Support for .dmg files is deprecated and may be removed in a future release`) await exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${tempInstallDir}`])
await exec.exec('hdiutil', ['attach', juliaDownloadPath]) return path.join(tempInstallDir, 'julia')
await exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${dest}`])
return path.join(dest, 'julia')
} else {
// tc.extractTar doesn't support stripping components, so we have to call tar manually
await exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', dest])
return dest
}
default: default:
throw new Error(`Platform ${osPlat} is not supported`) throw new Error(`Platform ${osPlat} is not supported`)
} }

View File

@@ -1,4 +1,5 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import * as exec from '@actions/exec'
import * as tc from '@actions/tool-cache' import * as tc from '@actions/tool-cache'
import * as fs from 'fs' import * as fs from 'fs'
@@ -7,16 +8,6 @@ import * as path from 'path'
import * as installer from './installer' import * as installer from './installer'
const archSynonyms = {
'x86': 'x86',
'X86': 'x86',
'x64': 'x64',
'X64': 'x64',
'aarch64': 'aarch64',
'ARM64': 'aarch64',
'arm64': 'aarch64'
}
async function run() { async function run() {
try { try {
// Debugging info // Debugging info
@@ -39,8 +30,7 @@ async function run() {
// Inputs // Inputs
const versionInput = core.getInput('version') const versionInput = core.getInput('version')
const includePrereleases = core.getInput('include-all-prereleases') == 'true' const arch = core.getInput('arch')
const originalArchInput = core.getInput('arch')
// It can easily happen that, for example, a workflow file contains an input `version: ${{ matrix.julia-version }}` // It can easily happen that, for example, a workflow file contains an input `version: ${{ matrix.julia-version }}`
// while the strategy matrix only contains a key `${{ matrix.version }}`. // while the strategy matrix only contains a key `${{ matrix.version }}`.
@@ -50,15 +40,13 @@ async function run() {
if (!versionInput) { if (!versionInput) {
throw new Error('Version input must not be null') throw new Error('Version input must not be null')
} }
if (!originalArchInput) { if (!arch) {
throw new Error(`Arch input must not be null`) throw new Error(`Arch input must not be null`)
} }
const arch = archSynonyms[originalArchInput]
const versionInfo = await installer.getJuliaVersionInfo() const versionInfo = await installer.getJuliaVersionInfo()
const availableReleases = await installer.getJuliaVersions(versionInfo) const availableReleases = await installer.getJuliaVersions(versionInfo)
const version = installer.getJuliaVersion(availableReleases, versionInput, includePrereleases) const version = installer.getJuliaVersion(availableReleases, versionInput)
core.debug(`selected Julia version: ${arch}/${version}`) core.debug(`selected Julia version: ${arch}/${version}`)
core.setOutput('julia-version', version) core.setOutput('julia-version', version)
@@ -68,21 +56,14 @@ async function run() {
if (!juliaPath) { if (!juliaPath) {
core.debug(`could not find Julia ${arch}/${version} in cache`) core.debug(`could not find Julia ${arch}/${version} in cache`)
const juliaInstallationPath = await installer.installJulia(versionInfo, version, arch)
// https://github.com/julia-actions/setup-julia/pull/196 // Add it to cache
// we want julia to be installed with unmodified file mtimes juliaPath = await tc.cacheDir(juliaInstallationPath, 'julia', version, arch)
// but `tc.cacheDir` uses `cp` internally which destroys mtime
// and `tc` provides no API to get the tool directory alone
// so hack it by installing a empty directory then use the path it returns
// and extract the archives directly to that location
const emptyDir = fs.mkdtempSync('empty')
juliaPath = await tc.cacheDir(emptyDir, 'julia', version, arch)
await installer.installJulia(juliaPath, versionInfo, version, arch)
core.debug(`added Julia to cache: ${juliaPath}`) core.debug(`added Julia to cache: ${juliaPath}`)
// Remove empty dir // Remove temporary dir
fs.rmdirSync(emptyDir) fs.rmdirSync(juliaInstallationPath, {recursive: true})
} else { } else {
core.debug(`using cached version of Julia: ${juliaPath}`) core.debug(`using cached version of Julia: ${juliaPath}`)
} }
@@ -97,7 +78,7 @@ async function run() {
const showVersionInfoInput = core.getInput('show-versioninfo') const showVersionInfoInput = core.getInput('show-versioninfo')
await installer.showVersionInfo(showVersionInfoInput, version) await installer.showVersionInfo(showVersionInfoInput, version)
} catch (error) { } catch (error) {
core.setFailed((error as Error).message) core.setFailed(error.message)
} }
} }