Compare commits

...

32 Commits

Author SHA1 Message Date
Sascha Mann
fac69f5780 Add TODO 2020-06-25 13:46:40 +02:00
Sascha Mann
ead3831d7a Cache artifacts directory by default 2020-06-25 13:39:22 +02:00
Sascha Mann
8945494c8c Document pre-release version range syntax -0
Also add a link to REPL.it to play with the version matching logic.
2020-06-01 22:48:13 +02:00
Sascha Mann
a81735fc3d Add Julia 1.5.0-beta1 2020-05-29 10:24:13 +02:00
Sascha Mann
2c2ccf4805 Add Julia 1.4.2 and update deps 2020-05-28 12:02:01 +02:00
Sascha Mann
0352b39425 Bump action version to 1.1.4 2020-04-15 14:04:09 +02:00
Sascha Mann
5ed1ab9531 Add Julia 1.4.1 2020-04-15 13:54:34 +02:00
Sascha Mann
b440227ef4 Use @zeit/ncc to distribute action 2020-03-24 20:05:33 +01:00
Sascha Mann
e07eb0ff2a Remove debugging steps from workflows 2020-03-22 18:16:49 +01:00
Sascha Mann
0c24e24eb5 Add Julia 1.4.0 2020-03-22 18:09:09 +01:00
Sascha Mann
abd4c5ae03 Run npm audit fix 2020-03-22 18:07:32 +01:00
Sascha Mann
51f7dbcff0 Add 'v1.4.0-rc2' 2020-03-11 14:19:14 +01:00
Sascha Mann
06264a4b68 Run npm audit fix --force 2020-03-11 14:19:14 +01:00
Sascha Mann
8f56a5b739 Remove @actions/github dependency
(fixes #27)
2020-03-11 14:19:02 +01:00
Sascha Mann
83f4f82909 Don't show versioninfo() by default (#25)
* Only show versioninfo() in debug mode

* Add input to specify if versioninfo() is displayed

* No access to secrets
2020-02-19 20:45:01 +01:00
Sascha Mann
eba5daa7a3 Add shell: bash to examples
fixes #23
2020-02-17 13:59:12 +01:00
Sascha Mann
150b180e77 Fix v1.4.0-rc1 version string 2020-02-13 10:48:40 +01:00
Sascha Mann
df27cccb6d Add Julia 1.4.0-rc1 to version list 2020-01-23 23:51:41 +01:00
Sascha Mann
4e8b9a1f06 Revert "Temporarily increase frequency of nightly builds"
This reverts commit 6c0c21977e.
2020-01-08 21:12:02 +01:00
Sascha Mann
960c1f45ca Delete release checklist
No longer needed, the bash script `bin/build-release` covers all of this.
2019-12-31 11:08:25 +01:00
Sascha Mann
ca58c641a5 Add Julia 1.3.1 to version list (#22) 2019-12-31 10:53:40 +01:00
Sascha Mann
6c0c21977e Temporarily increase frequency of nightly builds
The download of the nightly linux binaries still fails seemingly randomly. To get more information, the build will be run every 15 minutes temporarily.
2019-12-09 11:34:15 +01:00
Sascha Mann
6a79c57a32 Include debug info in CI builds (#19) 2019-12-05 20:21:48 +01:00
Sascha Mann
2efcc69643 Add Julia 1.3.0 to versions 2019-11-26 21:12:15 +01:00
Sascha Mann
d8b4778b2d Add (scheduled) CI runs (#15) 2019-11-26 17:05:08 +01:00
Sascha Mann
c8ae0bede2 Update versions in README 2019-11-25 14:56:26 +01:00
Sascha Mann
34454fe7cf Remove nightly from README TODOs 2019-11-25 14:22:23 +01:00
Sascha Mann
689d600802 Fix Windows install script 2019-11-25 14:22:23 +01:00
Sascha Mann
df485a1da6 Fix macOS install script 2019-11-25 14:22:23 +01:00
Sascha Mann
41539df7fe Fix linux install script 2019-11-25 14:22:23 +01:00
Sascha Mann
767e91ee6e Support nightly Julia builds 2019-11-25 14:22:23 +01:00
Sascha Mann
b199a80ea6 Add script to build test release 2019-11-25 14:22:23 +01:00
17 changed files with 2972 additions and 1144 deletions

View File

@@ -0,0 +1,36 @@
name: Example builds (nightly)
on:
push:
pull_request:
schedule:
- cron: '0 3 * * *'
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
julia-arch: [x64, x86]
os: [ubuntu-latest, macOS-latest, windows-latest]
# 32-bit Julia binaries are not available on macOS
exclude:
- os: macOS-latest
julia-arch: x86
steps:
- uses: actions/checkout@v1.0.0
- name: "Install dependencies"
run: |
npm install
npm run build
npm run pack
- name: "Set up Julia (nightly)"
uses: ./
with:
version: nightly
arch: ${{ matrix.julia-arch }}
- run: julia --version

33
.github/workflows/example-builds.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Example builds
on: [push, pull_request]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
julia-version: ['1.0.5', '1', '^1.5.0-beta1']
julia-arch: [x64, x86]
os: [ubuntu-latest, macOS-latest, windows-latest]
# 32-bit Julia binaries are not available on macOS
exclude:
- os: macOS-latest
julia-arch: x86
steps:
- uses: actions/checkout@v1.0.0
- name: "Install dependencies"
run: |
npm install
npm run build
npm run pack
- name: "Set up Julia"
uses: ./
with:
version: ${{ matrix.julia-version }}
arch: ${{ matrix.julia-arch }}
- run: julia --version

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
node_modules/ node_modules/
__tests__/runner/* __tests__/runner/*
dist/

View File

@@ -11,7 +11,6 @@ This action sets up a Julia environment for use in actions by downloading a spec
- [Julia Versions](#julia-versions) - [Julia Versions](#julia-versions)
- [Matrix Testing](#matrix-testing) - [Matrix Testing](#matrix-testing)
- [Versioning](#versioning) - [Versioning](#versioning)
- [Future plans & ideas](#future-plans--ideas)
- [Licence info](#licence-info) - [Licence info](#licence-info)
## Usage ## Usage
@@ -25,7 +24,7 @@ You can find a list of example workflows making use of this action here: [julia-
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v1.0.0 - uses: actions/checkout@v1.0.0
- uses: julia-actions/setup-julia@v0.2 - uses: julia-actions/setup-julia@v1
with: with:
version: 1.0.4 version: 1.0.4
- run: julia -e 'println("Hello, World!")' - run: julia -e 'println("Hello, World!")'
@@ -41,9 +40,11 @@ You can either specify specific Julia versions or version ranges. If you specify
- `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`. - `1.0` is a version range that will match the highest available Julia version that starts with `1.0`, e.g. `1.0.5`.
- `^1.3.0-rc1` is a caret version range that includes preleases. It matches all versions `≥ 1.3.0-rc1` and `< 1.4.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 `< 1.4.0`.
- `^1.3-0` is a caret version range that includes _all_ pre-releases. It matches all versions `≥ 1.3.0-` and `< 1.4.0`.
- `nightly` will install the latest nightly build.
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. 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).
#### WARNING: Version ranges are experimental and potentially out of date #### WARNING: Version ranges are experimental and potentially out of date
@@ -51,6 +52,8 @@ Currently the list of available versions is hardcoded. You have to use the lates
### Matrix Testing ### Matrix Testing
`bash` is chosen as shell to enforce consistent behaviour across operating systems. [Other shells](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell) are available but you may have to escape quotation marks or otherwise adjust the syntax.
#### 64-bit Julia only #### 64-bit Julia only
```yaml ```yaml
@@ -65,10 +68,11 @@ jobs:
steps: steps:
- uses: actions/checkout@v1.0.0 - uses: actions/checkout@v1.0.0
- name: "Set up Julia" - name: "Set up Julia"
uses: julia-actions/setup-julia@v0.2 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!")'
shell: bash
``` ```
#### 32-bit Julia #### 32-bit Julia
@@ -90,11 +94,12 @@ jobs:
steps: steps:
- uses: actions/checkout@v1.0.0 - uses: actions/checkout@v1.0.0
- name: "Set up Julia" - name: "Set up Julia"
uses: julia-actions/setup-julia@v0.2 uses: julia-actions/setup-julia@v1
with: with:
version: ${{ matrix.julia-version }} version: ${{ matrix.julia-version }}
arch: ${{ matrix.julia-arch }} arch: ${{ matrix.julia-arch }}
- run: julia -e 'println("Hello, World!")' - run: julia -e 'println("Hello, World!")'
shell: bash
``` ```
Alternatively, you can include specific version and OS combinations that will use 32-bit Julia: Alternatively, you can include specific version and OS combinations that will use 32-bit Julia:
@@ -116,10 +121,11 @@ jobs:
steps: steps:
- uses: actions/checkout@v1.0.0 - uses: actions/checkout@v1.0.0
- name: "Set up Julia" - name: "Set up Julia"
uses: julia-actions/setup-julia@v0.2 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!")'
shell: bash
``` ```
## Versioning ## Versioning
@@ -141,14 +147,5 @@ steps:
- uses: julia-actions/setup-julia@v0.1.0 # specific version tag - uses: julia-actions/setup-julia@v0.1.0 # specific version tag
``` ```
## Future plans & ideas
In no particular order:
* Check if a cached version of Julia is available instead of installing it everytime CI runs ([waiting on GitHub to add proper caching](https://twitter.com/natfriedman/status/1164210683979812869))
* Add support for nightly Julia builds.
* Add CI script that checks if tags have been updated on release.
* Hash and signature checks.
## Licence info ## Licence info
Parts of this software have been derived from the `setup-go` [action](https://github.com/actions/setup-go) and the [TypeScript Action Template](https://github.com/actions/typescript-action), both released by GitHub under the MIT licence. Parts of this software have been derived from the `setup-go` [action](https://github.com/actions/setup-go) and the [TypeScript Action Template](https://github.com/actions/typescript-action), both released by GitHub under the MIT licence.

View File

@@ -1,5 +1,7 @@
import * as installer from '../src/installer' import * as installer from '../src/installer'
import * as semver from 'semver'
const testVersions = ['v1.3.0-rc4', 'v1.3.0-rc3', 'v1.3.0-rc2', 'v1.0.5', 'v1.2.0', 'v1.3.0-rc1', 'v1.2.0-rc3', 'v1.3.0-alpha', 'v1.2.0-rc2', 'v1.2.0-rc1', 'v1.1.1', 'v1.0.4', 'v1.1.0', 'v1.1.0-rc2', 'v1.1.0-rc1', 'v1.0.3', 'v1.0.2', 'v1.0.1', 'v1.0.0'] const testVersions = ['v1.3.0-rc4', 'v1.3.0-rc3', 'v1.3.0-rc2', 'v1.0.5', 'v1.2.0', 'v1.3.0-rc1', 'v1.2.0-rc3', 'v1.3.0-alpha', 'v1.2.0-rc2', 'v1.2.0-rc1', 'v1.1.1', 'v1.0.4', 'v1.1.0', 'v1.1.0-rc2', 'v1.1.0-rc1', 'v1.0.3', 'v1.0.2', 'v1.0.1', 'v1.0.0']
describe('installer tests', () => { describe('installer tests', () => {
@@ -14,6 +16,10 @@ describe('installer tests', () => {
expect(await installer.getJuliaVersion(['v1.2.0', 'v1.3.0-alpha', 'v1.3.0-rc1', 'v1.3.0'], '1.3.0-alpha')).toEqual('1.3.0-alpha') expect(await installer.getJuliaVersion(['v1.2.0', 'v1.3.0-alpha', 'v1.3.0-rc1', 'v1.3.0'], '1.3.0-alpha')).toEqual('1.3.0-alpha')
expect(await installer.getJuliaVersion([], '1.3.0-rc2')).toEqual('1.3.0-rc2') expect(await installer.getJuliaVersion([], '1.3.0-rc2')).toEqual('1.3.0-rc2')
}) })
it('Doesn\'t change the version when given `nightly`', async () => {
expect(await installer.getJuliaVersion([], 'nightly')).toEqual('nightly')
expect(await installer.getJuliaVersion(testVersions, 'nightly')).toEqual('nightly')
})
}) })
describe('version ranges', () => { describe('version ranges', () => {
it('Chooses the highest available version that matches the input', async () => { it('Chooses the highest available version that matches the input', async () => {
@@ -24,4 +30,14 @@ describe('installer tests', () => {
}) })
}) })
}) })
describe('node-semver behaviour', () => {
describe('Windows installer change', () => {
it('Correctly understands >1.4.0', () => {
expect(semver.gtr('1.4.0-rc1', '1.3', {includePrerelease: true})).toBeTruthy()
expect(semver.gtr('1.4.0-DEV', '1.3', {includePrerelease: true})).toBeTruthy()
expect(semver.gtr('1.3.1', '1.3', {includePrerelease: true})).toBeFalsy()
expect(semver.gtr('1.3.2-rc1', '1.3', {includePrerelease: true})).toBeFalsy()
})
})
})
}) })

View File

@@ -9,9 +9,20 @@ inputs:
description: 'Architecture of the Julia binaries. Defaults to x64.' description: 'Architecture of the Julia binaries. Defaults to x64.'
required: false required: false
default: 'x64' default: 'x64'
show-versioninfo:
description: 'Display InteractiveUtils.versioninfo() after installing'
required: false
default: 'false'
cache-artifacts:
description: 'Cache ~/.julia/artifacts. Will fail if no file matches **/Project.toml.'
required: false
default: 'true'
outputs:
artifacts-cache-id:
description: 'The cache id of the artifacts cache.'
runs: runs:
using: 'node12' using: 'node12'
main: 'lib/setup-julia.js' main: 'dist/index.js'
branding: branding:
icon: 'download' icon: 'download'
color: 'green' color: 'green'

View File

@@ -1,13 +1,44 @@
#!/bin/sh #!/bin/sh
git checkout -b releases/"$1" branch_name="$(git symbolic-ref --short -q HEAD)"
version="v$(jq -r .version package.json)"
repo="$1"
if [ -z "$repo" ]; then
echo "ERROR: must specify repository"
exit 1
fi
echo "=== debug info ==="
echo "branch: $branch_name"
echo "version: $version"
echo "repo: $repo"
echo "=================="
echo ""
# Check that the version doesn't exist yet
version_exists="$(curl -s https://api.github.com/repos/"$repo"/tags -H "Accept: application/vnd.github.v3.full+json" | jq -r '.[] | select(.name == "'"$version"'") | .name')"
if [ -n "$version_exists" ]; then
echo "ERROR: version $version already exists"
exit 1
fi
git checkout -b releases/"$version"
npm install npm install
npm run build npm run build
npm test npm test
npm prune --production npm run pack
sed -i 's/node_modules/!node_modules/g' .gitignore sed -i 's/dist/!dist/g' .gitignore
git add node_modules git add dist
git commit -a -m "Add production dependencies & build" git commit -a -m "Add production dependencies & build"
git tag "$1"
# Tags
major_minor="$(sed 's/\.[^.]*$//' <<< "$version")"
major="$(sed 's/\.[^.]*$//' <<< "$major_minor")"
git tag "$version"
git tag -f "$major_minor"
git tag -f "$major"
git tag -f "latest"

36
bin/build-test-release Normal file
View File

@@ -0,0 +1,36 @@
#!/bin/sh
branch_name="$(git symbolic-ref --short -q HEAD)"
version="v$(jq -r .version package.json)"
repo="$1"
if [ -z "$repo" ]; then
echo "ERROR: must specify repository"
exit 1
fi
echo "=== debug info ==="
echo "branch: $branch_name"
echo "version: $version"
echo "repo: $repo"
echo "=================="
echo ""
# Check that the version doesn't exist yet
version_exists="$(curl -s https://api.github.com/repos/"$repo"/tags -H "Accept: application/vnd.github.v3.full+json" | jq -r '.[] | select(.name == "'"$version"'") | .name')"
if [ -n "$version_exists" ]; then
echo "ERROR: version $version already exists"
exit 1
fi
git checkout -B test/"$branch_name"/releases/"$version"
npm install
npm run build
npm test
npm run pack
# Add dist/ to git and commit it
sed -i 's/dist/!dist/g' .gitignore
git add dist
git commit -a -m "Add production dependencies & build"

View File

@@ -1,16 +0,0 @@
# Release checklist
Version: `1.b.c`
- [ ] Create release branch `releases/v1.b.c`
- [ ] Unignore `node_modules/` by adding `!` in front in `.gitignore`
- [ ] Delete `node_modules/`
- [ ] Install production dependencies: `npm install --production`
- [ ] Add `node_modules/`: `git add node_modules`
- [ ] Commit & push action: `git commit -a -m "Publish v1.b.c."`, then `git push`
- [ ] Test the action with an example package
- [ ] Create tags
- [ ] `v1.b.c` pointing at the last commit in `releases/v1.b.c`
- [ ] `latest` pointing at the latest version of the highest major version
- [ ] `v1` pointing at the latest `1.x.x` version
- [ ] Push tags

40
lib/caching.js generated Normal file
View File

@@ -0,0 +1,40 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
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 step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
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 });
const cache = __importStar(require("@actions/cache"));
const glob = __importStar(require("@actions/glob"));
const path = __importStar(require("path"));
// TODO: Change to hashFiles once https://github.com/actions/toolkit/issues/472 has been resolved
const md5File = __importStar(require("md5-file"));
const JULIA_HOME = path.join(`${process.env.HOME}`, '.julia');
/**
* Cache the ~/.julia/artifacts directory.
*/
function cacheArtifacts() {
return __awaiter(this, void 0, void 0, function* () {
// TODO: Add error handling in case no Project.toml files are present
const projectFiles = yield (yield glob.create('**/Project.toml')).glob();
let projectsHash = '';
projectFiles.forEach((f) => {
projectsHash.concat('-', md5File.sync(f));
});
const paths = [path.join(JULIA_HOME, 'artifacts')];
const key = `artifacts-${process.env.RUNNER_OS}-${projectsHash}`;
return cache.saveCache(paths, key);
});
}
exports.cacheArtifacts = cacheArtifacts;

41
lib/installer.js generated
View File

@@ -25,13 +25,17 @@ const semver = __importStar(require("semver"));
const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS) const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS)
core.debug(`platform: ${osPlat}`); core.debug(`platform: ${osPlat}`);
// This is temporary until we have a better way of fetching releases (see #1, #4 for details) // This is temporary until we have a better way of fetching releases (see #1, #4 for details)
exports.juliaVersions = ['v1.3.0-rc5', 'v1.3.0-rc4', 'v1.3.0-rc3', 'v1.3.0-rc2', 'v1.0.5', 'v1.2.0', 'v1.3.0-rc1', 'v1.2.0-rc3', 'v1.3.0-alpha', 'v1.2.0-rc2', 'v1.2.0-rc1', 'v1.1.1', 'v1.0.4', 'v1.1.0', 'v1.1.0-rc2', 'v1.1.0-rc1', 'v1.0.3', 'v1.0.2', 'v1.0.1', 'v1.0.0', 'v0.7.0', 'v1.0.0-rc1', 'v0.7.0-rc3', 'v0.7.0-rc2', 'v0.7.0-rc1', 'v0.7.0-beta2', 'v0.6.4', 'v0.7.0-beta', 'v0.7.0-alpha', 'v0.6.3', 'v0.6.2', 'v0.6.1', 'v0.6.0', 'v0.6.0-rc3', 'v0.6.0-rc2', 'v0.5.2', 'v0.6.0-rc1', 'v0.6.0-pre.beta', 'v0.5.1', 'v0.6.0-pre.alpha', 'v0.5.0', 'v0.4.7', 'v0.5.0-rc4', 'v0.5.0-rc3', 'v0.5.0-rc2', 'v0.5.0-rc1', 'v0.5.0-rc0', 'v0.4.6', 'v0.4.5', 'v0.4.4', 'v0.4.3', 'v0.4.2', 'v0.4.1', 'v0.3.12', 'v0.4.0', 'v0.4.0-rc4', 'v0.4.0-rc3', 'v0.4.0-rc2', 'v0.4.0-rc1', 'v0.3.11', 'v0.3.10', 'v0.3.9', 'v0.3.8', 'v0.3.7', 'v0.3.6', 'v0.3.5', 'v0.3.4', 'v0.3.3', 'v0.3.2', 'v0.3.1', 'v0.3.0', 'v0.3.0-rc4', 'v0.3.0-rc3', 'v0.3.0-rc2', 'v0.3.0-rc1', 'v0.2.0-rc1', 'v0.2.0-rc3', 'v0.2.0-rc4', 'v0.2.0', 'v0.2.0-rc2']; exports.juliaVersions = ['v1.5.0-beta1', 'v1.4.2', 'v1.4.1', 'v1.4.0', 'v1.4.0-rc2', 'v1.4.0-rc1', 'v1.3.1', 'v1.3.0', 'v1.3.0-rc5', 'v1.3.0-rc4', 'v1.3.0-rc3', 'v1.3.0-rc2', 'v1.0.5', 'v1.2.0', 'v1.3.0-rc1', 'v1.2.0-rc3', 'v1.3.0-alpha', 'v1.2.0-rc2', 'v1.2.0-rc1', 'v1.1.1', 'v1.0.4', 'v1.1.0', 'v1.1.0-rc2', 'v1.1.0-rc1', 'v1.0.3', 'v1.0.2', 'v1.0.1', 'v1.0.0', 'v0.7.0', 'v1.0.0-rc1', 'v0.7.0-rc3', 'v0.7.0-rc2', 'v0.7.0-rc1', 'v0.7.0-beta2', 'v0.6.4', 'v0.7.0-beta', 'v0.7.0-alpha', 'v0.6.3', 'v0.6.2', 'v0.6.1', 'v0.6.0', 'v0.6.0-rc3', 'v0.6.0-rc2', 'v0.5.2', 'v0.6.0-rc1', 'v0.6.0-pre.beta', 'v0.5.1', 'v0.6.0-pre.alpha', 'v0.5.0', 'v0.4.7', 'v0.5.0-rc4', 'v0.5.0-rc3', 'v0.5.0-rc2', 'v0.5.0-rc1', 'v0.5.0-rc0', 'v0.4.6', 'v0.4.5', 'v0.4.4', 'v0.4.3', 'v0.4.2', 'v0.4.1', 'v0.3.12', 'v0.4.0', 'v0.4.0-rc4', 'v0.4.0-rc3', 'v0.4.0-rc2', 'v0.4.0-rc1', 'v0.3.11', 'v0.3.10', 'v0.3.9', 'v0.3.8', 'v0.3.7', 'v0.3.6', 'v0.3.5', 'v0.3.4', 'v0.3.3', 'v0.3.2', 'v0.3.1', 'v0.3.0', 'v0.3.0-rc4', 'v0.3.0-rc3', 'v0.3.0-rc2', 'v0.3.0-rc1', 'v0.2.0-rc1', 'v0.2.0-rc3', 'v0.2.0-rc4', 'v0.2.0', 'v0.2.0-rc2'];
function getJuliaVersion(availableReleases, versionInput) { function getJuliaVersion(availableReleases, versionInput) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
if (semver.valid(versionInput) == versionInput) { if (semver.valid(versionInput) == versionInput) {
// versionInput is a valid version, use it directly // versionInput is a valid version, use it directly
return versionInput; return versionInput;
} }
// nightlies
if (versionInput == 'nightly') {
return 'nightly';
}
// Use the highest available version that matches versionInput // Use the highest available version that matches versionInput
let version = semver.maxSatisfying(availableReleases, versionInput); let version = semver.maxSatisfying(availableReleases, versionInput);
if (version == null) { if (version == null) {
@@ -47,9 +51,7 @@ function getMajorMinorVersion(version) {
return version.split('.').slice(0, 2).join('.'); return version.split('.').slice(0, 2).join('.');
} }
function getDownloadURL(version, arch) { function getDownloadURL(version, arch) {
const baseURL = 'https://julialang-s3.julialang.org/bin';
let platform; let platform;
const versionDir = getMajorMinorVersion(version);
if (osPlat === 'win32') { // Windows if (osPlat === 'win32') { // Windows
platform = 'winnt'; platform = 'winnt';
} }
@@ -65,6 +67,14 @@ function getDownloadURL(version, arch) {
else { else {
throw `Platform ${osPlat} is not supported`; throw `Platform ${osPlat} is not supported`;
} }
// nightlies
if (version == 'nightly') {
const baseURL = 'https://julialangnightlies-s3.julialang.org/bin';
return `${baseURL}/${platform}/${arch}/${getFileName('latest', arch)}`;
}
// normal versions
const baseURL = 'https://julialang-s3.julialang.org/bin';
const versionDir = getMajorMinorVersion(version);
return `${baseURL}/${platform}/${arch}/${versionDir}/${getFileName(version, arch)}`; return `${baseURL}/${platform}/${arch}/${versionDir}/${getFileName(version, arch)}`;
} }
function getFileName(version, arch) { function getFileName(version, arch) {
@@ -81,7 +91,12 @@ function getFileName(version, arch) {
ext = 'dmg'; ext = 'dmg';
} }
else if (osPlat === 'linux') { // Linux else if (osPlat === 'linux') { // Linux
versionExt = arch == 'x64' ? '-linux-x86_64' : '-linux-i686'; if (version == 'latest') { // nightly version
versionExt = arch == 'x64' ? '-linux64' : '-linux32';
}
else {
versionExt = arch == 'x64' ? '-linux-x86_64' : '-linux-i686';
}
ext = 'tar.gz'; ext = 'tar.gz';
} }
else { else {
@@ -98,15 +113,25 @@ function installJulia(version, arch) {
// Install it // Install it
switch (osPlat) { switch (osPlat) {
case 'linux': case 'linux':
const juliaExtractedFolder = yield tc.extractTar(juliaDownloadPath); // tc.extractTar doesn't support stripping components, so we have to call tar manually
return path.join(juliaExtractedFolder, `julia-${version}`); yield exec.exec('mkdir', [`${process.env.HOME}/julia`]);
yield exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', `${process.env.HOME}/julia`]);
return `${process.env.HOME}/julia`;
case 'win32': case 'win32':
const juliaInstallationPath = path.join('C:', 'Julia'); const juliaInstallationPath = path.join('C:', 'Julia');
yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${juliaInstallationPath}" -NoNewWindow -Wait`]); if (version == '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
yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${juliaInstallationPath}" -NoNewWindow -Wait`]);
}
else {
yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${juliaInstallationPath}" -NoNewWindow -Wait`]);
}
return juliaInstallationPath; return juliaInstallationPath;
case 'darwin': case 'darwin':
yield exec.exec('hdiutil', ['attach', juliaDownloadPath]); yield exec.exec('hdiutil', ['attach', juliaDownloadPath]);
return `/Volumes/Julia-${version}/Julia-${getMajorMinorVersion(version)}.app/Contents/Resources/julia`; yield exec.exec('mkdir', [`${process.env.HOME}/julia`]);
yield exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${process.env.HOME}`]);
return `${process.env.HOME}/julia`;
default: default:
throw `Platform ${osPlat} is not supported`; throw `Platform ${osPlat} is not supported`;
} }

15
lib/setup-julia.js generated
View File

@@ -20,6 +20,7 @@ const exec = __importStar(require("@actions/exec"));
const tc = __importStar(require("@actions/tool-cache")); const tc = __importStar(require("@actions/tool-cache"));
const path = __importStar(require("path")); const path = __importStar(require("path"));
const installer = __importStar(require("./installer")); const installer = __importStar(require("./installer"));
const jlcache = __importStar(require("./caching"));
function run() { function run() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
@@ -43,8 +44,18 @@ function run() {
} }
// Add it to PATH // Add it to PATH
core.addPath(path.join(juliaPath, 'bin')); core.addPath(path.join(juliaPath, 'bin'));
// Test if Julia has been installed by showing versioninfo() // Test if Julia has been installed
yield exec.exec('julia', ['-e', 'using InteractiveUtils; versioninfo()']); exec.exec('julia', ['--version']);
// If enabled, also show the full version info
if (core.getInput('show-versioninfo') == 'true') {
exec.exec('julia', ['-e', 'using InteractiveUtils; versioninfo()']);
}
// Create caches
if (core.getInput('cache-artifacts') == 'true') {
core.debug('caching artifacts directory...');
const cacheId = yield jlcache.cacheArtifacts();
core.setOutput('artifacts-cache-id', cacheId.toString());
}
} }
catch (error) { catch (error) {
core.setFailed(error.message); core.setFailed(error.message);

3701
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,12 @@
{ {
"name": "setup-julia", "name": "setup-julia",
"version": "0.1.0", "version": "1.1.6",
"private": true, "private": true,
"description": "setup Julia action", "description": "setup Julia action",
"main": "lib/setup-julia.js", "main": "lib/setup-julia.js",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"format": "prettier --single-quote --print-width 120 --tab-width 4 --no-semi --write **/*.ts", "pack": "ncc build",
"format-check": "prettier --single-quote --print-width 120 --tab-width 4 --no-semi --check **/*.ts",
"test": "jest" "test": "jest"
}, },
"repository": { "repository": {
@@ -22,21 +21,24 @@
"author": "Sascha Mann <git@mail.saschamann.eu>", "author": "Sascha Mann <git@mail.saschamann.eu>",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "^0.2.1",
"@actions/core": "^1.0.0", "@actions/core": "^1.0.0",
"@actions/exec": "^1.0.0", "@actions/exec": "^1.0.0",
"@actions/github": "^1.0.0", "@actions/glob": "^0.1.0",
"@actions/io": "^1.0.0", "@actions/io": "^1.0.0",
"@actions/tool-cache": "^1.0.0", "@actions/tool-cache": "^1.0.0",
"md5-file": "^5.0.0",
"semver": "^6.3.0" "semver": "^6.3.0"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^24.0.13", "@types/jest": "^24.0.13",
"@types/node": "^12.12.7", "@types/node": "^12.12.7",
"@types/semver": "^6.0.0", "@types/semver": "^6.0.0",
"@zeit/ncc": "^0.22.0",
"jest": "^24.8.0", "jest": "^24.8.0",
"jest-circus": "^24.7.1", "jest-circus": "^24.7.1",
"prettier": "^1.17.1", "prettier": "^1.17.1",
"ts-jest": "^24.0.2", "ts-jest": "^26.0.0",
"typescript": "^3.5.1" "typescript": "^3.5.1"
} }
} }

26
src/caching.ts Normal file
View File

@@ -0,0 +1,26 @@
import * as cache from '@actions/cache'
import * as glob from '@actions/glob'
import * as path from 'path'
// TODO: Change to hashFiles once https://github.com/actions/toolkit/issues/472 has been resolved
import * as md5File from 'md5-file'
const JULIA_HOME = path.join(`${process.env.HOME}`, '.julia')
/**
* Cache the ~/.julia/artifacts directory.
*/
export async function cacheArtifacts(): Promise<number> {
// TODO: Add error handling in case no Project.toml files are present
const projectFiles = await (await glob.create('**/Project.toml')).glob()
let projectsHash = ''
projectFiles.forEach((f) => {
projectsHash.concat('-', md5File.sync(f))
})
const paths = [path.join(JULIA_HOME, 'artifacts')]
const key = `artifacts-${process.env.RUNNER_OS}-${projectsHash}`
return cache.saveCache(paths, key)
}

View File

@@ -2,7 +2,6 @@ import * as core from '@actions/core'
import * as exec from '@actions/exec' import * as exec from '@actions/exec'
import * as tc from '@actions/tool-cache' import * as tc from '@actions/tool-cache'
import * as https from 'https'
import * as os from 'os' import * as os from 'os'
import * as path from 'path' import * as path from 'path'
@@ -13,7 +12,7 @@ const osPlat = os.platform() // possible values: win32 (Windows), linux (Linux),
core.debug(`platform: ${osPlat}`) core.debug(`platform: ${osPlat}`)
// This is temporary until we have a better way of fetching releases (see #1, #4 for details) // This is temporary until we have a better way of fetching releases (see #1, #4 for details)
export const juliaVersions = ['v1.3.0-rc5', 'v1.3.0-rc4', 'v1.3.0-rc3', 'v1.3.0-rc2', 'v1.0.5', 'v1.2.0', 'v1.3.0-rc1', 'v1.2.0-rc3', 'v1.3.0-alpha', 'v1.2.0-rc2', 'v1.2.0-rc1', 'v1.1.1', 'v1.0.4', 'v1.1.0', 'v1.1.0-rc2', 'v1.1.0-rc1', 'v1.0.3', 'v1.0.2', 'v1.0.1', 'v1.0.0', 'v0.7.0', 'v1.0.0-rc1', 'v0.7.0-rc3', 'v0.7.0-rc2', 'v0.7.0-rc1', 'v0.7.0-beta2', 'v0.6.4', 'v0.7.0-beta', 'v0.7.0-alpha', 'v0.6.3', 'v0.6.2', 'v0.6.1', 'v0.6.0', 'v0.6.0-rc3', 'v0.6.0-rc2', 'v0.5.2', 'v0.6.0-rc1', 'v0.6.0-pre.beta', 'v0.5.1', 'v0.6.0-pre.alpha', 'v0.5.0', 'v0.4.7', 'v0.5.0-rc4', 'v0.5.0-rc3', 'v0.5.0-rc2', 'v0.5.0-rc1', 'v0.5.0-rc0', 'v0.4.6', 'v0.4.5', 'v0.4.4', 'v0.4.3', 'v0.4.2', 'v0.4.1', 'v0.3.12', 'v0.4.0', 'v0.4.0-rc4', 'v0.4.0-rc3', 'v0.4.0-rc2', 'v0.4.0-rc1', 'v0.3.11', 'v0.3.10', 'v0.3.9', 'v0.3.8', 'v0.3.7', 'v0.3.6', 'v0.3.5', 'v0.3.4', 'v0.3.3', 'v0.3.2', 'v0.3.1', 'v0.3.0', 'v0.3.0-rc4', 'v0.3.0-rc3', 'v0.3.0-rc2', 'v0.3.0-rc1', 'v0.2.0-rc1', 'v0.2.0-rc3', 'v0.2.0-rc4', 'v0.2.0', 'v0.2.0-rc2'] export const juliaVersions = ['v1.5.0-beta1', 'v1.4.2', 'v1.4.1', 'v1.4.0', 'v1.4.0-rc2', 'v1.4.0-rc1', 'v1.3.1', 'v1.3.0', 'v1.3.0-rc5', 'v1.3.0-rc4', 'v1.3.0-rc3', 'v1.3.0-rc2', 'v1.0.5', 'v1.2.0', 'v1.3.0-rc1', 'v1.2.0-rc3', 'v1.3.0-alpha', 'v1.2.0-rc2', 'v1.2.0-rc1', 'v1.1.1', 'v1.0.4', 'v1.1.0', 'v1.1.0-rc2', 'v1.1.0-rc1', 'v1.0.3', 'v1.0.2', 'v1.0.1', 'v1.0.0', 'v0.7.0', 'v1.0.0-rc1', 'v0.7.0-rc3', 'v0.7.0-rc2', 'v0.7.0-rc1', 'v0.7.0-beta2', 'v0.6.4', 'v0.7.0-beta', 'v0.7.0-alpha', 'v0.6.3', 'v0.6.2', 'v0.6.1', 'v0.6.0', 'v0.6.0-rc3', 'v0.6.0-rc2', 'v0.5.2', 'v0.6.0-rc1', 'v0.6.0-pre.beta', 'v0.5.1', 'v0.6.0-pre.alpha', 'v0.5.0', 'v0.4.7', 'v0.5.0-rc4', 'v0.5.0-rc3', 'v0.5.0-rc2', 'v0.5.0-rc1', 'v0.5.0-rc0', 'v0.4.6', 'v0.4.5', 'v0.4.4', 'v0.4.3', 'v0.4.2', 'v0.4.1', 'v0.3.12', 'v0.4.0', 'v0.4.0-rc4', 'v0.4.0-rc3', 'v0.4.0-rc2', 'v0.4.0-rc1', 'v0.3.11', 'v0.3.10', 'v0.3.9', 'v0.3.8', 'v0.3.7', 'v0.3.6', 'v0.3.5', 'v0.3.4', 'v0.3.3', 'v0.3.2', 'v0.3.1', 'v0.3.0', 'v0.3.0-rc4', 'v0.3.0-rc3', 'v0.3.0-rc2', 'v0.3.0-rc1', 'v0.2.0-rc1', 'v0.2.0-rc3', 'v0.2.0-rc4', 'v0.2.0', 'v0.2.0-rc2']
export async function getJuliaVersion(availableReleases: string[], versionInput: string): Promise<string> { export async function getJuliaVersion(availableReleases: string[], versionInput: string): Promise<string> {
if (semver.valid(versionInput) == versionInput) { if (semver.valid(versionInput) == versionInput) {
@@ -21,6 +20,11 @@ export async function getJuliaVersion(availableReleases: string[], versionInput:
return versionInput return versionInput
} }
// nightlies
if (versionInput == 'nightly') {
return 'nightly'
}
// Use the highest available version that matches versionInput // Use the highest available version that matches versionInput
let version = semver.maxSatisfying(availableReleases, versionInput) let version = semver.maxSatisfying(availableReleases, versionInput)
if (version == null) { if (version == null) {
@@ -38,9 +42,7 @@ function getMajorMinorVersion(version: string): string {
} }
function getDownloadURL(version: string, arch: string): string { function getDownloadURL(version: string, arch: string): string {
const baseURL = 'https://julialang-s3.julialang.org/bin'
let platform: string let platform: string
const versionDir = getMajorMinorVersion(version)
if (osPlat === 'win32') { // Windows if (osPlat === 'win32') { // Windows
platform = 'winnt' platform = 'winnt'
@@ -55,6 +57,16 @@ function getDownloadURL(version: string, arch: string): string {
throw `Platform ${osPlat} is not supported` throw `Platform ${osPlat} is not supported`
} }
// nightlies
if (version == 'nightly') {
const baseURL = 'https://julialangnightlies-s3.julialang.org/bin'
return `${baseURL}/${platform}/${arch}/${getFileName('latest', arch)}`
}
// normal versions
const baseURL = 'https://julialang-s3.julialang.org/bin'
const versionDir = getMajorMinorVersion(version)
return `${baseURL}/${platform}/${arch}/${versionDir}/${getFileName(version, arch)}` return `${baseURL}/${platform}/${arch}/${versionDir}/${getFileName(version, arch)}`
} }
@@ -71,7 +83,11 @@ function getFileName(version: string, arch: string): string {
versionExt = '-mac64' versionExt = '-mac64'
ext = 'dmg' ext = 'dmg'
} else if (osPlat === 'linux') { // Linux } else if (osPlat === 'linux') { // Linux
versionExt = arch == 'x64' ? '-linux-x86_64' : '-linux-i686' if (version == 'latest') { // nightly version
versionExt = arch == 'x64' ? '-linux64' : '-linux32'
} else {
versionExt = arch == 'x64' ? '-linux-x86_64' : '-linux-i686'
}
ext = 'tar.gz' ext = 'tar.gz'
} else { } else {
throw `Platform ${osPlat} is not supported` throw `Platform ${osPlat} is not supported`
@@ -89,15 +105,24 @@ export async function installJulia(version: string, arch: string): Promise<strin
// Install it // Install it
switch (osPlat) { switch (osPlat) {
case 'linux': case 'linux':
const juliaExtractedFolder = await tc.extractTar(juliaDownloadPath) // tc.extractTar doesn't support stripping components, so we have to call tar manually
return path.join(juliaExtractedFolder, `julia-${version}`) await exec.exec('mkdir', [`${process.env.HOME}/julia`])
await exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', `${process.env.HOME}/julia`])
return `${process.env.HOME}/julia`
case 'win32': case 'win32':
const juliaInstallationPath = path.join('C:', 'Julia') const juliaInstallationPath = path.join('C:', 'Julia')
await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${juliaInstallationPath}" -NoNewWindow -Wait`]) if (version == '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
await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${juliaInstallationPath}" -NoNewWindow -Wait`])
} else {
await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${juliaInstallationPath}" -NoNewWindow -Wait`])
}
return juliaInstallationPath return juliaInstallationPath
case 'darwin': case 'darwin':
await exec.exec('hdiutil', ['attach', juliaDownloadPath]) await exec.exec('hdiutil', ['attach', juliaDownloadPath])
return `/Volumes/Julia-${version}/Julia-${getMajorMinorVersion(version)}.app/Contents/Resources/julia` await exec.exec('mkdir', [`${process.env.HOME}/julia`])
await exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${process.env.HOME}`])
return `${process.env.HOME}/julia`
default: default:
throw `Platform ${osPlat} is not supported` throw `Platform ${osPlat} is not supported`
} }

View File

@@ -5,6 +5,7 @@ import * as tc from '@actions/tool-cache'
import * as path from 'path' import * as path from 'path'
import * as installer from './installer' import * as installer from './installer'
import * as jlcache from './caching'
async function run() { async function run() {
try { try {
@@ -32,8 +33,20 @@ async function run() {
// Add it to PATH // Add it to PATH
core.addPath(path.join(juliaPath, 'bin')) core.addPath(path.join(juliaPath, 'bin'))
// Test if Julia has been installed by showing versioninfo() // Test if Julia has been installed
await exec.exec('julia', ['-e', 'using InteractiveUtils; versioninfo()']) exec.exec('julia', ['--version'])
// If enabled, also show the full version info
if (core.getInput('show-versioninfo') == 'true') {
exec.exec('julia', ['-e', 'using InteractiveUtils; versioninfo()'])
}
// Create caches
if (core.getInput('cache-artifacts') == 'true') {
core.debug('caching artifacts directory...')
const cacheId = await jlcache.cacheArtifacts()
core.setOutput('artifacts-cache-id', cacheId.toString())
}
} catch (error) { } catch (error) {
core.setFailed(error.message) core.setFailed(error.message)
} }