mirror of
				https://github.com/actions-rs/toolchain.git
				synced 2025-10-31 19:33:53 +00:00 
			
		
		
		
	Profiles and components support
This commit is contained in:
		
							parent
							
								
									74865b8fc9
								
							
						
					
					
						commit
						f0a61e6769
					
				
							
								
								
									
										47
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @ -1,18 +1,49 @@ | |||||||
| name: Continuous integration | name: Continuous integration | ||||||
| 
 | 
 | ||||||
| on: [pull_request, push] | on: [push] | ||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   check_pr: |   check_pr: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|     - uses: actions/checkout@v1 |       - name: Create npm configuration | ||||||
|  |         run: echo "//npm.pkg.github.com/:_authToken=${token}" >> ~/.npmrc | ||||||
|  |         env: | ||||||
|  |           token: ${{ secrets.GITHUB_TOKEN }} | ||||||
| 
 | 
 | ||||||
|     - name: "npm ci" |       - uses: actions/checkout@v1 | ||||||
|       run: npm ci |       - run: npm ci | ||||||
|  |       - run: npm run build | ||||||
|  |       - run: npm run test | ||||||
| 
 | 
 | ||||||
|     - name: "npm run build" |   install_stable: | ||||||
|       run: npm run build |     runs-on: ubuntu-latest | ||||||
|  |     needs: check_pr | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v1 | ||||||
|  |       - uses: ./ | ||||||
|  |         with: | ||||||
|  |           toolchain: stable | ||||||
| 
 | 
 | ||||||
|     - name: "npm run test" |   install_nightly: | ||||||
|       run: npm run test |     runs-on: ubuntu-latest | ||||||
|  |     needs: check_pr | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v1 | ||||||
|  |       - uses: ./ | ||||||
|  |         with: | ||||||
|  |           profile: minimal | ||||||
|  |           toolchain: nightly | ||||||
|  |           components: rustfmt, clippy | ||||||
|  | 
 | ||||||
|  |   install_stable_in_docker: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     container: ubuntu:latest  # Docker image, not the GitHub Actions VM | ||||||
|  |     needs: check_pr | ||||||
|  |     steps: | ||||||
|  |       # `rustup` will need `curl` or `wget` later | ||||||
|  |       - run: apt-get update && apt-get install -y curl | ||||||
|  |       - uses: actions/checkout@v1 | ||||||
|  |       - uses: ./ | ||||||
|  |         with: | ||||||
|  |           toolchain: stable | ||||||
|  | |||||||
| @ -4,6 +4,13 @@ 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.3] - 2019-10-19 | ||||||
|  | 
 | ||||||
|  | ### Added | ||||||
|  | 
 | ||||||
|  | - Support for `rustup set profile` command | ||||||
|  | - Support for `--component` flag for the `rustup toolchain install` command | ||||||
|  | 
 | ||||||
| ## [1.0.2] - 2019-10-14 | ## [1.0.2] - 2019-10-14 | ||||||
| 
 | 
 | ||||||
| ### Changed | ### Changed | ||||||
|  | |||||||
							
								
								
									
										70
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								README.md
									
									
									
									
									
								
							| @ -20,7 +20,7 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - uses: actions/checkout@master |       - uses: actions/checkout@master | ||||||
|       - name: Install nightly |       - name: Install latest nightly | ||||||
|         uses: actions-rs/toolchain@v1 |         uses: actions-rs/toolchain@v1 | ||||||
|         with: |         with: | ||||||
|             toolchain: nightly |             toolchain: nightly | ||||||
| @ -39,19 +39,67 @@ See [additional recipes here](https://github.com/actions-rs/meta). | |||||||
| 
 | 
 | ||||||
| ## Inputs | ## Inputs | ||||||
| 
 | 
 | ||||||
| | 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` | string |         | | | `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 |         | | ||||||
|  | | `components` |          | Comma-separated list of the additional components to install, ex. `clippy, rustfmt`                                                                 | string |         | | ||||||
|  | 
 | ||||||
|  | ## Profiles | ||||||
|  | 
 | ||||||
|  | This Action supports rustup [profiles](https://blog.rust-lang.org/2019/10/15/Rustup-1.20.0.html#profiles), | ||||||
|  | which are can be used to speed up the workflow execution by installing the | ||||||
|  | minimally required set of components, for example: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | - name: Install minimal nightly | ||||||
|  |   uses: actions-rs/toolchain@v1 | ||||||
|  |   with: | ||||||
|  |     profile: minimal | ||||||
|  |     toolchain: nightly | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | This Action will automatically run `rustup self update` if `profile` input is set | ||||||
|  | and the installed `rustup` version does not supports them. | ||||||
|  | 
 | ||||||
|  | In order to provide backwards compatibility for `v1` version, | ||||||
|  | there is no value for `profile` input set by default, | ||||||
|  | which means that the `default` profile is used by `rustup` | ||||||
|  | (and that includes `rust-docs`, `clippy` and `rustfmt`).\ | ||||||
|  | You may want to consider using `profile: minimal` to speed up toolchain installation. | ||||||
| 
 | 
 | ||||||
| ## Components | ## Components | ||||||
| 
 | 
 | ||||||
| If you are going to install `clippy`, `rustfmt` or any other [rustup component](https://rust-lang.github.io/rustup-components-history/), | This Action supports rustup [components](https://blog.rust-lang.org/2019/10/15/Rustup-1.20.0.html#installing-the-latest-compatible-nightly) too, | ||||||
| it might not be available in latest `nightly` build; | and in combination with the [profiles](#profiles) input it allows to install only the needed components: | ||||||
| check out the [`actions-rs/components-nightly`](https://github.com/actions-rs/components-nightly) Action, | 
 | ||||||
| which makes this process much easier. | ```yaml | ||||||
|  | - name: Install minimal stable with clippy and rustfmt | ||||||
|  |   uses: actions-rs/toolchain@v1 | ||||||
|  |   with: | ||||||
|  |     profile: minimal | ||||||
|  |     toolchain: nightly | ||||||
|  |     components: rustfmt, clippy | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | As an extra perk, `rustup >= 1.20.0` is able to find the most recent `nightly` toolchain | ||||||
|  | with the requested components available; next example is utilizing this feature | ||||||
|  | to install the minimal set of `nightly` toolchain components with the `rustfmt` and `clippy` extras: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | - name: Install minimal nightly with clippy and rustfmt | ||||||
|  |   uses: actions-rs/toolchain@v1 | ||||||
|  |   with: | ||||||
|  |     profile: minimal | ||||||
|  |     toolchain: nightly | ||||||
|  |     components: rustfmt, clippy | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Same to the `profile` input, if the installed `rustup` does not supports "components", | ||||||
|  | it will be automatically upgraded by this Action. | ||||||
| 
 | 
 | ||||||
| ## Notes | ## Notes | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -19,6 +19,12 @@ inputs: | |||||||
|   override: |   override: | ||||||
|     description: Set installed toolchain as an override for a directory |     description: Set installed toolchain as an override for a directory | ||||||
|     default: false |     default: false | ||||||
|  |   profile: | ||||||
|  |     description: Name of the group of components to be installed for a new toolchain | ||||||
|  |     required: false | ||||||
|  |   components: | ||||||
|  |     description: Comma-separated list of components to be additionally installed for a new toolchain | ||||||
|  |     required: false | ||||||
| 
 | 
 | ||||||
| runs: | runs: | ||||||
|   using: 'node12' |   using: 'node12' | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										5741
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5741
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "rust-toolchain", |     "name": "rust-toolchain", | ||||||
|     "version": "1.0.2", |     "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", | ||||||
| @ -32,7 +32,7 @@ | |||||||
|         "@actions/core": "^1.1.1", |         "@actions/core": "^1.1.1", | ||||||
|         "@actions/exec": "^1.0.0", |         "@actions/exec": "^1.0.0", | ||||||
|         "@actions/io": "^1.0.0", |         "@actions/io": "^1.0.0", | ||||||
|         "download": "^7.1.0" |         "@actions-rs/core": "^0.0.7" | ||||||
|     }, |     }, | ||||||
|     "devDependencies": { |     "devDependencies": { | ||||||
|         "@types/jest": "^24.0.19", |         "@types/jest": "^24.0.19", | ||||||
|  | |||||||
							
								
								
									
										47
									
								
								src/args.ts
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								src/args.ts
									
									
									
									
									
								
							| @ -1,43 +1,26 @@ | |||||||
| import * as core from '@actions/core'; | import * as core from '@actions/core'; | ||||||
| 
 | import {input} from '@actions-rs/core'; | ||||||
| // Workaround for a GH bug: https://github.com/actions/toolkit/issues/127
 |  | ||||||
| //
 |  | ||||||
| // For input `all-features: true` it will generate the `INPUT_ALL-FEATURES: true`
 |  | ||||||
| // env variable, which looks too weird.
 |  | ||||||
| // Here we are trying to get proper name `INPUT_NO_DEFAULT_FEATURES` first,
 |  | ||||||
| // and if it does not exist, trying the `INPUT_NO-DEFAULT-FEATURES`
 |  | ||||||
| function getInput(name: string, options?: core.InputOptions): string { |  | ||||||
|     const inputFullName = name.replace(/-/g, '_'); |  | ||||||
|     let value = core.getInput(inputFullName, options); |  | ||||||
|     if (value.length > 0) { |  | ||||||
|         return value |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return core.getInput(name) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function inputBoolean(name: string): boolean { |  | ||||||
|     const value = getInput(name); |  | ||||||
|     if (value == 'true' || value == '1') { |  | ||||||
|         return true; |  | ||||||
|     } else { |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| export interface ToolchainOptions { | export interface ToolchainOptions { | ||||||
|     name: string, |     name: string, | ||||||
|     target?: string, |     target: string | undefined, | ||||||
|     default: boolean, |     default: boolean, | ||||||
|     override: boolean |     override: boolean, | ||||||
|  |     profile: string | undefined, | ||||||
|  |     components: string[] | undefined, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function toolchain_args(): ToolchainOptions { | export function toolchain_args(): ToolchainOptions { | ||||||
|  |     let components: string[] | undefined = input.getInputList('components'); | ||||||
|  |     if (components && components.length === 0) { | ||||||
|  |         components = undefined; | ||||||
|  |     } | ||||||
|     return { |     return { | ||||||
|         name: getInput('toolchain', {required: true}), |         name: input.getInput('toolchain', {required: true}), | ||||||
|         target: getInput('target') || undefined, |         target: input.getInput('target') || undefined, | ||||||
|         default: inputBoolean('default'), |         default: input.getInputBool('default'), | ||||||
|         override: inputBoolean('override') |         override: input.getInputBool('override'), | ||||||
|  |         profile: input.getInput('profile') || undefined, | ||||||
|  |         components: components, | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										109
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										109
									
								
								src/main.ts
									
									
									
									
									
								
							| @ -1,91 +1,52 @@ | |||||||
| const os = require('os'); |  | ||||||
| const fs = require('fs'); |  | ||||||
| const path = require('path'); |  | ||||||
| const https = require('https'); |  | ||||||
| 
 |  | ||||||
| const download = require('download'); |  | ||||||
| 
 |  | ||||||
| import * as core from '@actions/core'; | import * as core from '@actions/core'; | ||||||
| import * as exec from '@actions/exec'; | import * as exec from '@actions/exec'; | ||||||
| import * as io from '@actions/io'; | import * as io from '@actions/io'; | ||||||
| 
 | 
 | ||||||
| import * as args from './args'; | import * as args from './args'; | ||||||
| 
 | import {RustUp, ToolchainOptions} from '@actions-rs/core'; | ||||||
| function downloadRustInit(url: string, name: string): Promise<string> { |  | ||||||
|     const absPath = path.join(os.tmpdir(), name); |  | ||||||
| 
 |  | ||||||
|     return new Promise((resolve, reject) => { |  | ||||||
|         let req = download(url); |  | ||||||
|         let output = fs.createWriteStream(absPath, { |  | ||||||
|             mode: 0o755 |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         req.pipe(output); |  | ||||||
|         req.on('end', () => { |  | ||||||
|             output.close(resolve); |  | ||||||
|         }); |  | ||||||
|         req.on('error', reject); |  | ||||||
|         output.on('error', reject); |  | ||||||
|     }) |  | ||||||
|     .then(() => { |  | ||||||
|         return absPath; |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| async function get_rustup(toolchain: string): Promise<string> { |  | ||||||
|     try { |  | ||||||
|         const foundPath = await io.which('rustup', true); |  | ||||||
|         core.debug(`Found rustup at ${foundPath}`); |  | ||||||
|         return foundPath; |  | ||||||
|     } catch (error) { |  | ||||||
|         core.info('Unable to find rustup, installing it now'); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     let args = [ |  | ||||||
|         '-y', |  | ||||||
|         '--default-toolchain', |  | ||||||
|         toolchain, |  | ||||||
|     ]; |  | ||||||
| 
 |  | ||||||
|     // Note: `target` input can't be used here for `--default-host` argument, see #8
 |  | ||||||
| 
 |  | ||||||
|     switch (process.platform) { |  | ||||||
|         case 'darwin': |  | ||||||
|         case 'linux':  // Should be installed already, but just in case
 |  | ||||||
|             const rustupSh = await downloadRustInit('https://sh.rustup.rs', 'rustup-init.sh'); |  | ||||||
|             await exec.exec(rustupSh, args); |  | ||||||
|             break; |  | ||||||
| 
 |  | ||||||
|         case 'win32': |  | ||||||
|             const rustupExe = await downloadRustInit('http://win.rustup.rs', 'rustup-init.exe'); |  | ||||||
|             await exec.exec(rustupExe, args); |  | ||||||
|             break; |  | ||||||
| 
 |  | ||||||
|         default: |  | ||||||
|             throw new Error(`Unknown platform ${process.platform}, can't install rustup`); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     core.addPath(path.join(process.env['HOME'], '.cargo', 'bin')); |  | ||||||
| 
 |  | ||||||
|     return 'rustup'; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| async function run() { | async function run() { | ||||||
|     const opts = args.toolchain_args(); |     const opts = args.toolchain_args(); | ||||||
|     const rustup = await get_rustup(opts.name); |     const rustup = await RustUp.getOrInstall(); | ||||||
|  |     await rustup.call(['show']); | ||||||
| 
 | 
 | ||||||
|     await exec.exec(rustup, ['toolchain', 'install', opts.name]); |     let shouldSelfUpdate = false; | ||||||
| 
 |     if (opts.profile && !await rustup.supportProfiles()) { | ||||||
|     if (opts.default) { |         shouldSelfUpdate = true; | ||||||
|         await exec.exec(rustup, ['default', opts.name]); |     } | ||||||
|  |     if (opts.components && !await rustup.supportComponents()) { | ||||||
|  |         shouldSelfUpdate = true; | ||||||
|  |     } | ||||||
|  |     if (shouldSelfUpdate) { | ||||||
|  |         core.startGroup('Updating rustup'); | ||||||
|  |         try { | ||||||
|  |             await rustup.selfUpdate(); | ||||||
|  |         } finally { | ||||||
|  |             core.endGroup(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (opts.override) { |     if (opts.profile) { | ||||||
|         await exec.exec(rustup, ['override', 'set', opts.name]); |         //@ts-ignore
 | ||||||
|  |         await rustup.setProfile(opts.profile); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     let installOptions: ToolchainOptions = { | ||||||
|  |         default: opts.default, | ||||||
|  |         override: opts.override, | ||||||
|  |     }; | ||||||
|  |     if (opts.components) { | ||||||
|  |         installOptions.components = opts.components; | ||||||
|  |     } | ||||||
|  |     // We already did it just now, there is no reason to do that again,
 | ||||||
|  |     // so it would skip few network calls.
 | ||||||
|  |     if (shouldSelfUpdate) { | ||||||
|  |         installOptions.noSelfUpdate = true; | ||||||
|  |     } | ||||||
|  |     await rustup.installToolchain(opts.name, installOptions); | ||||||
|  | 
 | ||||||
|     if (opts.target) { |     if (opts.target) { | ||||||
|         await exec.exec(rustup, ['target', 'add', '--toolchain', opts.name, opts.target]); |         await rustup.addTarget(opts.target, opts.name); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user