Compare commits

..

No commits in common. "master" and "v1.0.3" have entirely different histories.

20 changed files with 7207 additions and 5757 deletions

View File

@ -1,19 +0,0 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.eslint.json"
},
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
"prettier",
"prettier/@typescript-eslint"
],
"rules": {
"@typescript-eslint/ban-ts-ignore": "off"
}
}

View File

@ -1,15 +0,0 @@
#!/bin/bash
# This commit hook checks whether we ran `npm run build` when committed TypeScript files.
# For GitHub actions to work, we need to check the compiled JavaScript into VCS.
#
# This script can yield false positives in cases where you only make stylistic changes to the TypeScript code that don't result in changes to the compiled JavaScript code.
# It is your responsibility as a developer to then commit the changes with `git commit --no-verify` and simply skip this commit hook.
TS_FILES=$(git diff --staged --name-only | grep -c '\.ts$')
DIST_MODIFIED=$(git diff --staged --name-only | grep -c dist/index.js)
if [ $TS_FILES -gt 0 ] && [ $DIST_MODIFIED -eq 0 ] ; then
echo "You modified TypeScript files but apparently did not run 'npm run build'".
exit 1;
fi

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
custom: https://svartalf.info/donate/

View File

@ -1,9 +1,9 @@
name: Continuous integration name: Continuous integration
on: [push, pull_request] on: [push]
jobs: jobs:
test: check_pr:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Create npm configuration - name: Create npm configuration
@ -13,39 +13,21 @@ jobs:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- run: npm ci - run: npm ci
# Temporary disabling in order to release urgent fix
# - run: npm run lint
- run: npm run build - run: npm run build
- run: npm run test - run: npm run test
install_stable: install_stable:
runs-on: ${{ matrix.os }} runs-on: ubuntu-latest
strategy: needs: check_pr
matrix:
os:
- ubuntu-latest
- macOS-latest
- windows-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- id: toolchain - uses: ./
uses: ./
with: with:
toolchain: stable toolchain: stable
- name: Test toolchain outputs
env:
RUSTC: ${{ steps.toolchain.outputs.rustc }}
RUSTC_HASH: ${{ steps.toolchain.outputs.rustc_hash }}
CARGO: ${{ steps.toolchain.outputs.cargo }}
RUSTUP: ${{ steps.toolchain.outputs.rustup }}
run: |
echo $RUSTC
echo $RUSTC_HASH
echo $CARGO
echo $RUSTUP
install_nightly: install_nightly:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: check_pr
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- uses: ./ - uses: ./
@ -57,6 +39,7 @@ jobs:
install_stable_in_docker: install_stable_in_docker:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: ubuntu:latest # Docker image, not the GitHub Actions VM container: ubuntu:latest # Docker image, not the GitHub Actions VM
needs: check_pr
steps: steps:
# `rustup` will need `curl` or `wget` later # `rustup` will need `curl` or `wget` later
- run: apt-get update && apt-get install -y curl - run: apt-get update && apt-get install -y curl
@ -64,10 +47,3 @@ jobs:
- uses: ./ - uses: ./
with: with:
toolchain: stable toolchain: stable
install_stable_through_rust_toolchain_file:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: echo "stable" > ./rust-toolchain
- uses: ./

3
.gitignore vendored
View File

@ -89,6 +89,3 @@ typings/
# DynamoDB Local files # DynamoDB Local files
.dynamodb/ .dynamodb/
# IntelliJ IDEs
.idea

View File

@ -4,26 +4,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.6] - 2020-03-24 ### [1.0.3] - 2019-10-19
### Added
- Pass `allow-downgrade` flag to `rustup` if `nightly` toolchain with components requested
## [1.0.5] - 2020-01-26
### Fixed
- `rustup` version parser does not fail Action execution on `macOS-latest` VM images anymore
## [1.0.4] - 2020-01-26
### Added
- Support for the `rust-toolchain` file: If the toolchain input is not given, we will try and install the version specified in the `rust-toolchain` file.
- Action outputs with `rustc`, `cargo` and `rustup` versions installed
## [1.0.3] - 2019-10-19
### Added ### Added

View File

@ -1,27 +1,11 @@
# `rust-toolchain` Action # `rust-toolchain` Action
[![Sponsoring](https://img.shields.io/badge/Support%20it-Say%20%22Thank%20you!%22-blue)](https://actions-rs.github.io/#sponsoring)
![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg) ![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)
[![Gitter](https://badges.gitter.im/actions-rs/community.svg)](https://gitter.im/actions-rs/community) [![Gitter](https://badges.gitter.im/actions-rs/community.svg)](https://gitter.im/actions-rs/community)
![Continuous integration](https://github.com/actions-rs/toolchain/workflows/Continuous%20integration/badge.svg)
![Dependabot enabled](https://api.dependabot.com/badges/status?host=github&repo=actions-rs/toolchain)
This GitHub Action installs [Rust toolchain](https://rust-lang.github.io/rustup/concepts/toolchains.html#toolchain-specification) This GitHub Action installs [Rust toolchain](https://github.com/rust-lang/rustup.rs#toolchain-specification).
with [rustup](https://github.com/rust-lang/rustup) help.
It supports additional targets, components and profiles and handles all Optionally it can set installed toolchain as a default and as an override for current directory.
these small papercuts for you.
**Table of Contents**
* [Example workflow](#example-workflow)
* [Inputs](#inputs)
* [Outputs](#outputs)
* [Profiles](#profiles)
* [Components](#components)
* [The toolchain file](#the-toolchain-file)
* [License](#license)
* [Contribute and support](#contribute-and-support)
## Example workflow ## Example workflow
@ -35,16 +19,15 @@ jobs:
name: Rust project name: Rust project
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@master
- name: Install latest nightly - name: Install latest nightly
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: nightly toolchain: nightly
override: true override: true
components: rustfmt, clippy
# `cargo check` command here will use installed `nightly` # `cargo check` command here will use installed `nightly`
# as it is set as an "override" for current directory # as it set as an "override" for current directory
- name: Run cargo check - name: Run cargo check
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
@ -58,30 +41,13 @@ See [additional recipes here](https://github.com/actions-rs/meta).
| Name | Required | Description | Type | Default | | Name | Required | Description | Type | Default |
| ------------ | :------: | ----------------------------------------------------------------------------------------------------------------------------------------------------| ------ | --------| | ------------ | :------: | ----------------------------------------------------------------------------------------------------------------------------------------------------| ------ | --------|
| `toolchain` | | [Toolchain](https://github.com/rust-lang/rustup.rs#toolchain-specification) name to use, ex. `stable`, `nightly`, `nightly-2019-04-20`, or `1.32.0` | string | stable | | `toolchain` | | [Toolchain](https://github.com/rust-lang/rustup.rs#toolchain-specification) name to use, ex. `stable`, `nightly`, `nightly-2019-04-20`, or `1.32.0` | string | |
| `target` | | Additionally install specified target for this toolchain, ex. `x86_64-apple-darwin` | string | | | `target` | | Additionally install specified target for this toolchain, ex. `x86_64-apple-darwin` | string | |
| `default` | | Set installed toolchain as a default toolchain | bool | false | | `default` | | Set installed toolchain as a default toolchain | bool | false |
| `override` | | Set installed toolchain as an override for the current directory | bool | false | | `override` | | Set installed toolchain as an override for the current directory | bool | false |
| `profile` | | Execute `rustup set profile {value}` before installing the toolchain, ex. `minimal` | string | default | | `profile` | | Execute `rustup set profile {value}` before installing the toolchain, ex. `minimal` | string | |
| `components` | | Comma-separated list of the additional components to install, ex. `clippy, rustfmt` | string | | | `components` | | Comma-separated list of the additional components to install, ex. `clippy, rustfmt` | string | |
Note: since `v1.0.4` version, `toolchain` input is not marked as required
in order to support toolchain files. See the details [below](#the-toolchain-file).
## Outputs
Installed `rustc`, `cargo` and `rustup` versions can be fetched from the Action outputs:
| Name | Description | Example |
| ------------ | --------------------- | ------------------------------- |
| `rustc` | Rustc version | `1.40.0 (73528e339 2019-12-16)` |
| `rustc_hash` | Rustc version hash | `73528e339` |
| `cargo` | Cargo version | `1.40.0 (bc8e4c8be 2019-11-22)` |
| `rustup` | rustup version | `1.21.1 (7832b2ebe 2019-12-20)` |
Note: `rustc_hash` output value can be used with [actions/cache](https://github.com/actions/cache) Action
to store cache for different Rust versions, as it is unique across different Rust versions and builds (including `nightly`).
## Profiles ## Profiles
This Action supports rustup [profiles](https://blog.rust-lang.org/2019/10/15/Rustup-1.20.0.html#profiles), This Action supports rustup [profiles](https://blog.rust-lang.org/2019/10/15/Rustup-1.20.0.html#profiles),
@ -115,7 +81,7 @@ and in combination with the [profiles](#profiles) input it allows to install onl
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
profile: minimal profile: minimal
toolchain: stable toolchain: nightly
components: rustfmt, clippy components: rustfmt, clippy
``` ```
@ -132,38 +98,10 @@ to install the minimal set of `nightly` toolchain components with the `rustfmt`
components: rustfmt, clippy components: rustfmt, clippy
``` ```
In case if `nightly` toolchain is requested and one of the components is missing in Same to the `profile` input, if the installed `rustup` does not supports "components",
latest `nightly` release, this Action will attempt the downgrade till it find
the most recent `nightly` with all components needed.\
Note that this behavior will work only if the following two conditions apply:
1. `toolchain` input is `nightly` exactly.
2. At least one component is provided in `components` input.
Same to the `profile` input, if installed `rustup` does not supports "components",
it will be automatically upgraded by this Action. it will be automatically upgraded by this Action.
## The toolchain file ## Notes
This Action supports [toolchain files](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file), As `rustup` is not installed by default for [macOS environments](https://help.github.com/en/articles/virtual-environments-for-github-actions)
so it is not necessary to use `toolchain` input anymore. at the moment (2019-09-13), this Action will try its best to install it before any other operations.
Input has higher priority, so if you are want to use toolchain file,
you need to remove the input from the workflow file.
If neither `toolchain` input or `rust-toolchain` file are provided,
Action execution will fail.
## License
This Action is distributed under the terms of the MIT license, see [LICENSE](https://github.com/actions-rs/toolchain/blob/master/LICENSE) for details.
## Contribute and support
Any contributions are welcomed!
If you want to report a bug or have a feature request,
check the [Contributing guide](https://github.com/actions-rs/.github/blob/master/CONTRIBUTING.md).
You can also support author by funding the ongoing project work,
see [Sponsoring](https://actions-rs.github.io/#sponsoring).

View File

@ -1,74 +1,22 @@
import { getToolchainArgs } from "../src/args"; import * as args from '../src/args'
import { morph } from "mock-env";
import { sync as tempWriteSync } from "temp-write";
describe("actions-rs/toolchain", () => { const testEnvVars = {
it("Parses action input into toolchain options", () => { INPUT_TOOLCHAIN: 'nightly-2019-04-20',
const args = morph( INPUT_DEFAULT: 'false',
() => { INPUT_OVERRIDE: 'true'
return getToolchainArgs("./rust-toolchain"); }
},
{
INPUT_TOOLCHAIN: "nightly-2019-04-20",
INPUT_DEFAULT: "false",
INPUT_OVERRIDE: "true",
}
);
expect(args.name).toBe("nightly-2019-04-20"); describe('actions-rs/toolchain', () => {
expect(args.default).toBe(false); beforeEach(() => {
expect(args.override).toBe(true); for (const key in testEnvVars)
}); process.env[key] = testEnvVars[key as keyof typeof testEnvVars]
})
it("uses input variable if rust-toolchain file does not exist", function () { it('Parses action input into toolchain options', async () => {
const args = morph( const result = args.toolchain_args();
() => {
return getToolchainArgs("./rust-toolchain");
},
{
INPUT_TOOLCHAIN: "nightly",
}
);
expect(args.name).toBe("nightly"); expect(result.name).toBe('nightly-2019-04-20');
}); expect(result.default).toBe(false);
expect(result.override).toBe(true);
it("toolchain input is required if rust-toolchain does not exist", function () {
expect(() => getToolchainArgs("./rust-toolchain")).toThrowError();
});
it("prioritizes rust-toolchain file over input variable", function () {
const rustToolchainFile = tempWriteSync("1.39.0");
const args = morph(
() => {
return getToolchainArgs(rustToolchainFile);
},
{
INPUT_TOOLCHAIN: "nightly",
}
);
expect(args.name).toBe("nightly");
});
it("uses rust-toolchain file if input does not exist", function () {
const rustToolchainFile = tempWriteSync("1.39.0");
const args = morph(() => {
return getToolchainArgs(rustToolchainFile);
}, {});
expect(args.name).toBe("1.39.0");
});
it("trims content of the override file", function () {
const rustToolchainFile = tempWriteSync("\n 1.39.0\n\n\n\n");
const args = morph(() => {
return getToolchainArgs(rustToolchainFile);
}, {});
expect(args.name).toBe("1.39.0");
}); });
}); });

View File

@ -9,10 +9,7 @@ inputs:
description: | description: |
Rust toolchain name. Rust toolchain name.
See https://rust-lang.github.io/rustup/concepts/toolchains.html#toolchain-specification See https://github.com/rust-lang/rustup.rs#toolchain-specification
If this is not given, the action will try and install the version specified in the `rust-toolchain` file.
required: false
target: target:
description: Target triple to install for this toolchain description: Target triple to install for this toolchain
required: false required: false
@ -29,16 +26,6 @@ inputs:
description: Comma-separated list of components to be additionally installed for a new toolchain description: Comma-separated list of components to be additionally installed for a new toolchain
required: false required: false
outputs:
rustc:
description: Installed Rustc version
rustc_hash:
description: Installed Rustc version hash, can be used for caching purposes
cargo:
description: Installed Cargo version
rustup:
description: Installed rustup version
runs: runs:
using: 'node12' using: 'node12'
main: 'dist/index.js' main: 'dist/index.js'

2
dist/index.js vendored

File diff suppressed because one or more lines are too long

11
jest.config.js Normal file
View File

@ -0,0 +1,11 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: true
}

View File

@ -1,11 +0,0 @@
{
"clearMocks": true,
"moduleFileExtensions": ["js", "ts"],
"testEnvironment": "node",
"testMatch": ["**/*.test.ts"],
"testRunner": "jest-circus/runner",
"transform": {
"^.+\\.ts$": "ts-jest"
},
"verbose": true
}

12179
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "rust-toolchain", "name": "rust-toolchain",
"version": "1.0.7", "version": "1.0.3",
"private": false, "private": false,
"description": "Install the Rust toolchain", "description": "Install the Rust toolchain",
"main": "lib/main.js", "main": "lib/main.js",
@ -9,12 +9,9 @@
"test": "__tests__" "test": "__tests__"
}, },
"scripts": { "scripts": {
"build": "rm -rf ./dist/* && ncc build src/main.ts --minify", "build": "ncc build src/main.ts --minify",
"format": "prettier --write 'src/**/*.ts' '__tests__/**/*.ts'", "watch": "ncc build src/main.ts --watch",
"lint": "tsc --noEmit && eslint 'src/**/*.ts' '__tests__/**/*.ts'", "test": "jest"
"watch": "rm -rf ./dist/* && ncc build src/main.ts --watch",
"test": "jest -c jest.config.json",
"pretest": "git config core.hooksPath .githooks"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -32,27 +29,18 @@
"url": "https://github.com/actions-rs/toolchain/issues" "url": "https://github.com/actions-rs/toolchain/issues"
}, },
"dependencies": { "dependencies": {
"@actions-rs/core": "^0.1.6", "@actions/core": "^1.1.1",
"@actions/core": "^1.2.6", "@actions/exec": "^1.0.0",
"@actions/exec": "^1.0.4", "@actions/io": "^1.0.0",
"@actions/io": "^1.0.2" "@actions-rs/core": "^0.0.7"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^26.0.15", "@types/jest": "^24.0.19",
"@types/node": "^14.14.7", "@types/node": "^12.11.1",
"@typescript-eslint/eslint-plugin": "^4.8.1", "@zeit/ncc": "^0.20.5",
"@typescript-eslint/parser": "^4.8.1", "jest": "^24.9.0",
"@zeit/ncc": "^0.22.3", "jest-circus": "^24.9.0",
"eslint": "^7.13.0", "ts-jest": "^24.1.0",
"eslint-config-prettier": "^6.15.0", "typescript": "^3.6.4"
"eslint-plugin-prettier": "^3.1.4",
"jest": "^26.6.3",
"jest-circus": "^26.6.3",
"mock-env": "^0.2.0",
"npm-check-updates": "^10.2.1",
"prettier": "^2.1.2",
"temp-write": "^4.0.0",
"ts-jest": "^26.4.4",
"typescript": "^4.0.5"
} }
} }

View File

@ -1,52 +1,26 @@
import { input } from "@actions-rs/core"; import * as core from '@actions/core';
import { debug } from "@actions/core"; import {input} from '@actions-rs/core';
import { existsSync, readFileSync } from "fs";
export interface ToolchainOptions { export interface ToolchainOptions {
name: string; name: string,
target: string | undefined; target: string | undefined,
default: boolean; default: boolean,
override: boolean; override: boolean,
profile: string | undefined; profile: string | undefined,
components: string[] | undefined; components: string[] | undefined,
} }
function determineToolchain(overrideFile: string): string { export function toolchain_args(): ToolchainOptions {
const toolchainInput = input.getInput("toolchain", { required: false }); let components: string[] | undefined = input.getInputList('components');
if (toolchainInput) {
debug(`using toolchain from input: ${toolchainInput}`);
return toolchainInput;
}
if (!existsSync(overrideFile)) {
throw new Error(
"toolchain input was not given and repository does not have a rust-toolchain file"
);
}
const rustToolchainFile = readFileSync(overrideFile, {
encoding: "utf-8",
flag: "r",
}).trim();
debug(`using toolchain from rust-toolchain file: ${rustToolchainFile}`);
return rustToolchainFile;
}
export function getToolchainArgs(overrideFile: string): ToolchainOptions {
let components: string[] | undefined = input.getInputList("components");
if (components && components.length === 0) { if (components && components.length === 0) {
components = undefined; components = undefined;
} }
return { return {
name: determineToolchain(overrideFile), name: input.getInput('toolchain', {required: true}),
target: input.getInput("target") || undefined, target: input.getInput('target') || undefined,
default: input.getInputBool("default"), default: input.getInputBool('default'),
override: input.getInputBool("override"), override: input.getInputBool('override'),
profile: input.getInput("profile") || undefined, profile: input.getInput('profile') || undefined,
components: components, components: components,
}; };
} }

View File

@ -1,27 +1,24 @@
import * as core from "@actions/core"; import * as core from '@actions/core';
import path from "path"; import * as exec from '@actions/exec';
import * as io from '@actions/io';
import * as args from "./args"; import * as args from './args';
import * as versions from "./versions"; import {RustUp, ToolchainOptions} from '@actions-rs/core';
import { RustUp, ToolchainOptions } from "@actions-rs/core";
async function run(): Promise<void> { async function run() {
// we use path.join to make sure this works on Windows, Linux and MacOS const opts = args.toolchain_args();
const toolchainOverridePath = path.join(process.cwd(), "rust-toolchain");
const opts = args.getToolchainArgs(toolchainOverridePath);
const rustup = await RustUp.getOrInstall(); const rustup = await RustUp.getOrInstall();
await rustup.call(["show"]); await rustup.call(['show']);
let shouldSelfUpdate = false; let shouldSelfUpdate = false;
if (opts.profile && !(await rustup.supportProfiles())) { if (opts.profile && !await rustup.supportProfiles()) {
shouldSelfUpdate = true; shouldSelfUpdate = true;
} }
if (opts.components && !(await rustup.supportComponents())) { if (opts.components && !await rustup.supportComponents()) {
shouldSelfUpdate = true; shouldSelfUpdate = true;
} }
if (shouldSelfUpdate) { if (shouldSelfUpdate) {
core.startGroup("Updating rustup"); core.startGroup('Updating rustup');
try { try {
await rustup.selfUpdate(); await rustup.selfUpdate();
} finally { } finally {
@ -30,11 +27,11 @@ async function run(): Promise<void> {
} }
if (opts.profile) { if (opts.profile) {
// @ts-ignore: TS2345 //@ts-ignore
await rustup.setProfile(opts.profile); await rustup.setProfile(opts.profile);
} }
const installOptions: ToolchainOptions = { let installOptions: ToolchainOptions = {
default: opts.default, default: opts.default,
override: opts.override, override: opts.override,
}; };
@ -46,47 +43,14 @@ async function run(): Promise<void> {
if (shouldSelfUpdate) { if (shouldSelfUpdate) {
installOptions.noSelfUpdate = true; installOptions.noSelfUpdate = true;
} }
// Extra funny case.
// Due to `rustup` issue (https://github.com/rust-lang/rustup/issues/2146)
// right now installing `nightly` toolchain with extra components might fail
// if that specific `nightly` version does not have this component
// available.
//
// See https://github.com/actions-rs/toolchain/issues/53 also.
//
// By default `rustup` does not downgrade, as it does when you are
// updating already installed `nightly`, so we need to pass the
// corresponding flag manually.
//
// We are doing it only if both following conditions apply:
//
// 1. Requested toolchain is `"nightly"` (exact string match).
// 2. At least one component is requested.
//
// All other cases are not triggering automatic downgrade,
// for example, installing specific nightly version
// as in `"nightly-2020-03-20"` or `"stable"`.
//
// Motivation is that users probably want the latest one nightly
// with rustfmt and clippy (miri, etc) and they don't really care
// about what exact nightly it is.
// In case if it's not the nightly at all or it is a some specific
// nightly version, they know what they are doing.
if (opts.name == "nightly" && opts.components) {
installOptions.allowDowngrade = true;
}
await rustup.installToolchain(opts.name, installOptions); await rustup.installToolchain(opts.name, installOptions);
if (opts.target) { if (opts.target) {
await rustup.addTarget(opts.target, opts.name); await rustup.addTarget(opts.target, opts.name);
} }
await versions.gatherInstalledVersions();
} }
async function main(): Promise<void> { async function main() {
try { try {
await run(); await run();
} catch (error) { } catch (error) {

View File

@ -1,114 +0,0 @@
import * as exec from "@actions/exec";
import * as core from "@actions/core";
interface Version {
long: string;
hash: string;
}
/**
* Try to parse the version parts and return them.
*
* It is important to note that some components are not providing
* all the expected information, ex. `rustup` on `macOS-latest` VM image
* does not has the hash in the version string,
* so this function might throw an error.
*
* As a fallback, `parseShort` function can be used.
*/
function parseFull(stdout: string): Version {
const regex = /\S+\s((\S+)\s\((\S+)\s(\S+)\))/m;
stdout = stdout.trim();
const matches = regex.exec(stdout);
if (matches == null) {
throw new Error(`Unable to parse version from the "${stdout}" string`);
}
return {
long: matches[1],
hash: matches[3],
};
}
function parseShort(stdout: string): string {
const regex = /\S+\s(.+)/m;
stdout = stdout.trim();
const matches = regex.exec(stdout);
if (matches == null) {
core.warning(`Unable to determine version from the "${stdout}" string`);
return "";
} else {
return matches[1];
}
}
async function getStdout(
exe: string,
args: string[],
options?: {}
): Promise<string> {
let stdout = "";
const resOptions = Object.assign({}, options, {
listeners: {
stdout: (buffer: Buffer): void => {
stdout += buffer.toString();
},
},
});
await exec.exec(exe, args, resOptions);
return stdout;
}
/**
* Fetch currently used `rustc` version
*/
async function rustc(): Promise<void> {
const stdout = await getStdout("rustc", ["-V"]);
try {
const version = parseFull(stdout);
core.setOutput("rustc", version.long);
core.setOutput("rustc_hash", version.hash);
} catch (e) {
core.warning(e);
core.setOutput("rustc", parseShort(stdout));
}
}
/**
* Fetch currently used `cargo` version
*/
async function cargo(): Promise<void> {
const stdout = await getStdout("cargo", ["-V"]);
try {
const version = parseFull(stdout);
core.setOutput("cargo", version.long);
} catch (e) {
core.setOutput("cargo", parseShort(stdout));
}
}
async function rustup(): Promise<void> {
const stdout = await getStdout("rustup", ["-V"]);
try {
const version = parseFull(stdout);
core.setOutput("rustup", version.long);
} catch (e) {
core.setOutput("rustup", parseShort(stdout));
}
}
export async function gatherInstalledVersions(): Promise<void> {
try {
core.startGroup("Gathering installed versions");
await rustc();
await cargo();
await rustup();
} finally {
core.endGroup();
}
}

View File

@ -1,7 +0,0 @@
{
"extends": "./tsconfig.json",
"include": [
"src/**/*.ts",
"__tests__/**/*.ts"
]
}

View File

@ -1,32 +1,63 @@
{ {
"compilerOptions": { "compilerOptions": {
"allowJs": false, /* Basic Options */
"checkJs": false, // "incremental": true, /* Enable incremental compilation */
"esModuleInterop": true, "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"forceConsistentCasingInFileNames": true, "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"module": "commonjs", // "allowJs": true, /* Allow javascript files to be compiled. */
"moduleResolution": "node", // "checkJs": true, /* Report errors in .js files. */
"newLine": "LF", // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
"noEmitOnError": true, // "declaration": true, /* Generates corresponding '.d.ts' file. */
"noErrorTruncation": true, // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"noFallthroughCasesInSwitch": true, // "sourceMap": true, /* Generates corresponding '.map' file. */
"noImplicitAny": true, // "outFile": "./", /* Concatenate and emit output to single file. */
"noImplicitReturns": true, "outDir": "./lib", /* Redirect output structure to the directory. */
"noImplicitThis": true, "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"noUnusedLocals": true, // "composite": true, /* Enable project compilation */
"noUnusedParameters": true, // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
"outDir": "dist", // "removeComments": true, /* Do not emit comments to output. */
"pretty": true, // "noEmit": true, /* Do not emit outputs. */
"removeComments": true, // "importHelpers": true, /* Import emit helpers from 'tslib'. */
"resolveJsonModule": true, // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
"strict": true, // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
"suppressImplicitAnyIndexErrors": false,
"target": "es2018", /* Strict Type-Checking Options */
"declaration": false, "strict": true, /* Enable all strict type-checking options. */
"sourceMap": false, "noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
"typeRoots": ["./types", "./node_modules/@types"] // "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
}, },
"include": [ "exclude": ["node_modules", "**/*.test.ts"]
"src/**/*.ts"
]
} }

View File

@ -1,7 +0,0 @@
declare module "mock-env" {
function morph<T>(
callback: () => T,
vars: object,
toRemove?: string[]
): any;
}