├── .gitattributes ├── .github ├── dependabot.yaml └── workflows │ ├── build.yml │ ├── dart.yml │ └── publish.yml ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── DEVELOPING.md ├── LICENSE ├── README.md ├── action.yml ├── analysis_options.yaml ├── dist ├── index.mjs ├── main.cjs └── sig.txt ├── example ├── .gitignore ├── bin │ └── main.dart ├── pubspec.yaml └── test │ └── example_test.dart ├── lib ├── main.dart ├── main.mjs └── node │ ├── actions │ ├── core.dart │ ├── exec.dart │ ├── http_client.dart │ └── tool_cache.dart │ ├── fs.dart │ ├── os.dart │ └── process.dart ├── package-lock.json ├── package.json ├── pubspec.yaml └── tool └── sig.dart /.gitattributes: -------------------------------------------------------------------------------- 1 | dist/** -diff linguist-generated=true 2 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | # Dependabot configuration file - enable regular dependency checks. 2 | version: 2 3 | 4 | updates: 5 | - package-ecosystem: github-actions 6 | directory: / 7 | schedule: 8 | interval: monthly 9 | labels: 10 | - autosubmit 11 | groups: 12 | github-actions: 13 | patterns: 14 | - "*" 15 | 16 | - package-ecosystem: npm 17 | directory: / 18 | schedule: 19 | interval: monthly 20 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # Validate that the compiled artifacts are up-to-date. 2 | 3 | name: Build 4 | 5 | on: 6 | pull_request: 7 | branches: [main] 8 | schedule: 9 | - cron: "0 0 * * 0" # Run every Sunday at 00:00. 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: ./ 17 | with: 18 | sdk: dev 19 | - run: dart pub get 20 | - run: dart analyze --fatal-infos 21 | - run: dart tool/sig.dart --verify 22 | - run: npm run build 23 | -------------------------------------------------------------------------------- /.github/workflows/dart.yml: -------------------------------------------------------------------------------- 1 | # Tests for general `setup-dart` configurations. 2 | 3 | name: Dart 4 | 5 | on: 6 | push: 7 | branches: [main] 8 | pull_request: 9 | branches: [main] 10 | schedule: 11 | - cron: "0 0 * * 0" # Run every Sunday at 00:00. 12 | 13 | jobs: 14 | 15 | # Default test configurations. 16 | test: 17 | runs-on: ${{ matrix.os }} 18 | defaults: 19 | run: 20 | working-directory: example 21 | strategy: 22 | matrix: 23 | os: [ubuntu-latest, macos-latest, windows-latest] 24 | sdk: [2.14.4, stable, beta, dev] 25 | fail-fast: false 26 | steps: 27 | - uses: actions/checkout@v4 28 | - uses: ./ 29 | with: 30 | sdk: ${{ matrix.sdk }} 31 | 32 | - name: Print DART_HOME 33 | run: echo "Dart SDK installed in $DART_HOME" 34 | - run: dart pub get 35 | - run: dart run bin/main.dart 36 | - run: dart analyze 37 | - run: dart test 38 | 39 | # Test the raw SDK flavor. 40 | test_raw: 41 | runs-on: ${{ matrix.os }} 42 | strategy: 43 | matrix: 44 | os: [ubuntu-latest, macos-latest, windows-latest] 45 | sdk: [dev, main] 46 | flavor: [raw] 47 | fail-fast: false 48 | steps: 49 | - uses: actions/checkout@v4 50 | - uses: ./ 51 | with: 52 | sdk: ${{ matrix.sdk }} 53 | 54 | - name: Run hello world 55 | run: | 56 | echo "main() { print('hello world'); }" > hello.dart 57 | dart hello.dart 58 | 59 | # Test the architecture input parameter. 60 | test_arch: 61 | runs-on: windows-latest 62 | steps: 63 | - uses: actions/checkout@v4 64 | - uses: ./ 65 | with: 66 | architecture: ia32 67 | 68 | - name: Run hello world 69 | run: | 70 | echo "main() { print('hello world'); }" > hello.dart 71 | dart hello.dart 72 | 73 | # Test inferring the channel from the sdk parameter. 74 | test_inferred_channels: 75 | runs-on: ubuntu-latest 76 | strategy: 77 | matrix: 78 | sdk: [2.12.0-29.10.beta] 79 | fail-fast: false 80 | steps: 81 | - uses: actions/checkout@v4 82 | - uses: ./ 83 | with: 84 | sdk: ${{ matrix.sdk }} 85 | 86 | - name: Run hello world 87 | run: | 88 | echo "main() { print('hello world'); }" > hello.dart 89 | dart hello.dart 90 | - run: dart --version 91 | 92 | # Test getting the latest patch release for a major.minor sdk parameter. 93 | test_latest_patch_release: 94 | runs-on: ubuntu-latest 95 | strategy: 96 | matrix: 97 | sdk: [2.19, 3.0, 3.1] 98 | fail-fast: false 99 | steps: 100 | - uses: actions/checkout@v4 101 | - uses: ./ 102 | with: 103 | sdk: ${{ matrix.sdk }} 104 | 105 | - name: Run hello world 106 | run: | 107 | echo "main() { print('hello world'); }" > hello.dart 108 | dart hello.dart 109 | - run: dart --version 110 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to pub.dev 2 | 3 | ## Caller of this workflow should use it as follows: 4 | ## jobs: 5 | ## publish: 6 | ## uses: dart-lang/setup-dart/.github/workflows/publish.yml@main [or a recent commit hash / version tag] 7 | ## # with: 8 | ## # working-directory: path/to/sub/directory 9 | 10 | on: 11 | workflow_call: 12 | inputs: 13 | environment: 14 | description: If specified, the workflow is required to be run in this environment (with additional approvals). 15 | required: false 16 | type: string 17 | working-directory: 18 | description: The directory within the repository where the package is located (if not in the repository root). 19 | required: false 20 | type: string 21 | 22 | jobs: 23 | publish: 24 | name: 'Publish to pub.dev' 25 | environment: ${{ inputs.environment }} 26 | permissions: 27 | id-token: write # This is required for requesting the JWT 28 | runs-on: ubuntu-latest 29 | steps: 30 | # Checkout repository 31 | - uses: actions/checkout@v4 32 | # Set up the Dart SDK and provision the OIDC token used for publishing. 33 | # The `dart` command from this step will be shadowed by the one from the 34 | # Flutter SDK below. 35 | - uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c 36 | # Download flutter SDK - needed for publishing Flutter packages. Can also 37 | # publish pure Dart packages. 38 | # 39 | # The dart binary from a Flutter SDK facilitates publishing both Flutter 40 | # and pure-dart packages. 41 | - uses: flutter-actions/setup-flutter@54feb1e258158303e041b9eaf89314dcfbf6d38a 42 | # Minimal package setup and dry run checks. 43 | - name: Install dependencies 44 | run: dart pub get 45 | working-directory: ${{ inputs.working-directory }} 46 | - name: Publish - dry run 47 | run: dart pub publish --dry-run 48 | working-directory: ${{ inputs.working-directory }} 49 | # Publishing... 50 | - name: Publish to pub.dev 51 | run: dart pub publish -f 52 | working-directory: ${{ inputs.working-directory }} 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dart files 2 | .dart_tool/ 3 | pubspec.lock 4 | 5 | # node modules 6 | node_modules/ 7 | 8 | # intermediary compilation artifacts 9 | lib/main.js 10 | lib/main.js.deps 11 | lib/main.js.map 12 | 13 | lib/sig.txt 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v1.7.1 2 | 3 | * Roll `undici` dependency to address [CVE-2025-22150][]. 4 | * Update to the latest npm dependencies. 5 | * Recompile the action using the new Dart / JavaScript interop. 6 | 7 | [CVE-2025-22150]: https://github.com/nodejs/undici/security/advisories/GHSA-c76h-2ccp-4975 8 | 9 | ## v1.7.0 10 | 11 | * Install flutter sdk in publishing step, allowing Flutter packages to be 12 | published ([#68][]) 13 | 14 | [#68]: https://github.com/dart-lang/setup-dart/issues/68 15 | 16 | ## v1.6.5 17 | 18 | * Fix zip path handling on Windows 11 ([#118][]) 19 | 20 | [#118]: https://github.com/dart-lang/setup-dart/issues/118 21 | 22 | ## v1.6.4 23 | 24 | * Rebuild JS code. 25 | 26 | ## v1.6.3 27 | 28 | * Roll `undici` dependency to address [CVE-2024-30260][] and [CVE-2024-30261][]. 29 | 30 | [CVE-2024-30260]: https://github.com/nodejs/undici/security/advisories/GHSA-m4v8-wqvr-p9f7 31 | [CVE-2024-30261]: https://github.com/nodejs/undici/security/advisories/GHSA-9qxr-qj54-h672 32 | 33 | ## v1.6.2 34 | 35 | * Switch to running the workflow on `node20`` from `node16`. See also 36 | [Transitioning from Node 16 to Node 20][]. 37 | 38 | [Transitioning from Node 16 to Node 20]: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/ 39 | 40 | ## v1.6.1 41 | 42 | * Updated the google storage url for `main` channel releases. 43 | 44 | ## v1.6.0 45 | 46 | * Enable provisioning of the latest Dart SDK patch release by specifying just 47 | the major and minor version (e.g. `3.2`). 48 | 49 | ## v1.5.1 50 | 51 | * No longer test the `setup-dart` action on pre-2.12 SDKs. 52 | * Upgrade JS interop code to use extension types 53 | (the new name for inline classes). 54 | * The upcoming rename of the `be` channel to `main` is now supported with 55 | forward compatibility that switches when the rename happens. 56 | 57 | ## v1.5.0 58 | 59 | * Re-wrote the implementation of the action into Dart. 60 | * Auto-detect the platform architecture (`x64`, `ia32`, `arm`, `arm64`). 61 | * Improved the caching and download resilience of the sdk. 62 | * Added a new action output: `dart-version` - the installed version of the sdk. 63 | 64 | ## v1.4.0 65 | 66 | * Automatically create OIDC token for pub.dev. 67 | * Add a reusable workflow for publishing. 68 | 69 | ## v1.3.0 70 | 71 | * The install location of the Dart SDK is now available 72 | in an environment variable, `DART_HOME` 73 | ([#43](https://github.com/dart-lang/setup-dart/issues/43)). 74 | * Fixed an issue where cached downloads could lead to unzip issues 75 | on self-hosted runners 76 | ([#35](https://github.com/dart-lang/setup-dart/issues/35)). 77 | 78 | ## v1.2.0 79 | 80 | * Fixed a path issue impacting git dependencies on Windows. 81 | 82 | ## v1.1.0 83 | 84 | * Added a `flavor` option setup.sh to allow downloading unpublished builds. 85 | 86 | ## v1.0.0 87 | 88 | * Promoted to 1.0 stable. 89 | 90 | ## v0.5 91 | 92 | * Fixed a Windows `pub global activate` path issue. 93 | 94 | ## v0.4 95 | 96 | * Removed previously deprecated input `channel`. Use the `sdk` input instead. 97 | * Added support for specifying the CPU architecture. 98 | 99 | ## v0.3 100 | 101 | * Added support for installing SDKs from the `main` channel. 102 | 103 | ## v0.2 104 | 105 | * Added support for installing a specific SDK version (e.g. `2.10.0`). 106 | 107 | ## v0.1 108 | 109 | * Initial version. 110 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement (CLA). You (or your employer) retain the copyright to your 10 | contribution; this simply gives us permission to use and redistribute your 11 | contributions as part of the project. Head over to 12 | to see your current agreements on file or 13 | to sign a new one. 14 | 15 | You generally only need to submit a CLA once, so if you've already submitted one 16 | (even if it was for a different project), you probably don't need to do it 17 | again. 18 | 19 | ## Start with an issue 20 | 21 | Prior to sending patches and contributions to this project, please file an issue 22 | in the issue tracker to ensure there is alignment with the overall goals of this 23 | project. Thanks! 24 | 25 | ## Code Reviews 26 | 27 | All submissions, including submissions by project members, require review. We 28 | use GitHub pull requests for this purpose. Consult 29 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 30 | information on using pull requests. 31 | 32 | ## Coding style 33 | 34 | The Dart source code in this repo follows the: 35 | 36 | * [Dart style guide](https://dart.dev/guides/language/effective-dart/style) 37 | 38 | You should familiarize yourself with those guidelines. 39 | 40 | ## File headers 41 | 42 | All files in the Dart project must start with the following header; if you add a 43 | new file please also add this. The year should be a single number stating the 44 | year the file was created (don't use a range like "2011-2012"). Additionally, if 45 | you edit an existing file, you shouldn't update the year. 46 | 47 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 48 | // for details. All rights reserved. Use of this source code is governed by a 49 | // BSD-style license that can be found in the LICENSE file. 50 | 51 | ## Building and testing 52 | 53 | See the [DEVELOPING.md](DEVELOPING.md) file. 54 | 55 | ## Community Guidelines 56 | 57 | This project follows 58 | [Google's Open Source Community Guidelines](https://opensource.google/conduct/). 59 | 60 | We pledge to maintain an open and welcoming environment. For details, see our 61 | [code of conduct](https://dart.dev/code-of-conduct). 62 | -------------------------------------------------------------------------------- /DEVELOPING.md: -------------------------------------------------------------------------------- 1 | [![Build](https://github.com/dart-lang/setup-dart/actions/workflows/build.yml/badge.svg)](https://github.com/dart-lang/setup-dart/actions/workflows/build.yml) 2 | [![Dart](https://github.com/dart-lang/setup-dart/actions/workflows/dart.yml/badge.svg)](https://github.com/dart-lang/setup-dart/actions/workflows/dart.yml) 3 | 4 | ## Setting up 5 | 6 | 1. Install node 7 | 1. Install additional node tooling (`npm i -g @vercel/ncc`) 8 | 1. Install the node package dependencies (`npm install`) 9 | 10 | ## Development 11 | 12 | tldr: edit Dart source files and run `npm run all` to re-compile the action 13 | 14 | ### Working on the action 15 | 16 | Generally, to work on the action, edit the Dart source code in `lib/` and 17 | re-compile the JavaScript code via `npm run all`. This will: 18 | 19 | - compile the Dart source (via dart2js) to `lib/main.js`; copy that file to 20 | `dist/main.cjs` 21 | - package and minify the `lib/main.mjs` entrypoint point and referenced node 22 | modules to `dist/index.mjs` 23 | 24 | ### Files 25 | 26 | - `lib/main.dart` - the Dart entry-point to the action 27 | - `lib/main.mjs` - the JavaScript wrapper; this sets up some important JS 28 | interop globals and bootstraps into `lib/main.dart` 29 | - `dist/index.mjs` - the execution entry-point of the action 30 | 31 | ## Releasing 32 | 33 | See our 34 | [publishing](https://github.com/dart-lang/setup-dart/wiki/Publishing-procedure) 35 | wiki page. 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2020, the Dart project authors. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following 11 | disclaimer in the documentation and/or other materials provided 12 | with the distribution. 13 | * Neither the name of Google LLC nor the names of its 14 | contributors may be used to endorse or promote products derived 15 | from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # setup-dart 2 | 3 | [setup-dart][] installs and sets up a Dart SDK for use in GitHub Actions; it: 4 | 5 | * downloads the Dart SDK 6 | * adds the [`dart`](https://dart.dev/tools/dart-tool) tool to the system path 7 | 8 | [setup-dart]: https://github.com/marketplace/actions/setup-dart-sdk 9 | 10 | ## Usage 11 | 12 | To install the latest stable Dart SDK and run typical checks: 13 | 14 | ```yml 15 | name: Dart 16 | 17 | on: 18 | pull_request: 19 | branches: [main] 20 | push: 21 | branches: [main] 22 | 23 | jobs: 24 | build: 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v4 28 | - uses: dart-lang/setup-dart@v1 29 | 30 | - run: dart pub get 31 | - run: dart format --output=none --set-exit-if-changed . 32 | - run: dart analyze 33 | - run: dart test 34 | ``` 35 | 36 | ## Inputs 37 | 38 | The action takes the following inputs: 39 | 40 | * `sdk`: Which SDK version to setup. Can be specified using one of three forms: 41 | * A release channel, which will install the latest build from that channel. 42 | Available channels are `stable`, `beta`, `dev`, and `main`. See the 43 | [Dart SDK archive](https://dart.dev/get-dart/archive) for details. 44 | * An SDK release version - e.g. `2.19` or `3.1`. This will install the 45 | latest patch release for that specific release version. 46 | * A specific SDK version, e.g. `2.19.0` or `2.12.0-1.4.beta`. 47 | 48 | * `flavor`: Which build flavor to setup. 49 | * The available build flavors are `release` and `raw`. 50 | * The `release` flavor contains published builds. 51 | * The `raw` flavor contains unpublished builds; these can be used by 52 | developers to test against SDK versions before a signed release is 53 | available. Note that the `main` release channel only supports the `raw` 54 | build flavor. 55 | 56 | * `architecture`: The CPU architecture to setup support for. 57 | * Valid options are `x64`, `ia32`, `arm`, and `arm64`. 58 | * Note that not all CPU architectures are supported on all operating 59 | systems; see the 60 | [Dart system requirements](https://dart.dev/get-dart#system-requirements) 61 | for valid combinations. 62 | 63 | ## Outputs 64 | 65 | The action produces the following output: 66 | 67 | * `dart-version`: The version of the Dart SDK that was installed. 68 | 69 | ## Matrix testing example 70 | 71 | You can create matrix jobs that run tests on multiple operating systems, and 72 | multiple versions of the Dart SDK. 73 | 74 | The following example creates a matrix across two dimensions: 75 | 76 | - three major operating systems: Linux, MacOS, and Windows 77 | - several Dart SDK versions: a specific version, the latest stable, beta, and 78 | dev 79 | 80 | ```yml 81 | name: Dart 82 | 83 | on: 84 | push: 85 | branches: [main] 86 | pull_request: 87 | branches: [main] 88 | 89 | jobs: 90 | test: 91 | runs-on: ${{ matrix.os }} 92 | strategy: 93 | matrix: 94 | os: [ubuntu-latest, macos-latest, windows-latest] 95 | sdk: [3.1, stable, beta] 96 | steps: 97 | - uses: actions/checkout@v4 98 | - uses: dart-lang/setup-dart@v1 99 | with: 100 | sdk: ${{ matrix.sdk }} 101 | 102 | - name: Install dependencies 103 | run: dart pub get 104 | 105 | - name: Run tests 106 | run: dart test 107 | ``` 108 | 109 | ## License 110 | 111 | See the [LICENSE](LICENSE) file. 112 | 113 | ## Contributing 114 | 115 | Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md). 116 | 117 | ## Version history 118 | 119 | Please see our [CHANGELOG.md](CHANGELOG.md) file. 120 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: "Setup Dart SDK" 2 | description: "Download and setup the Dart SDK." 3 | branding: 4 | icon: check-circle 5 | color: blue 6 | inputs: 7 | sdk: 8 | description: >- 9 | This can be either the channel to install (i.e., 'stable', 'beta', 'dev'), 10 | an SDK release version (i.e., '2.19', '3.1'), or a specific SDK version 11 | (i.e, '2.19.1', '3.0.0-1.4.beta'). 12 | required: false 13 | default: "stable" 14 | architecture: 15 | description: "The CPU architecture ('x64', 'ia32', 'arm', or 'arm64')." 16 | required: false 17 | flavor: 18 | description: "The build flavor ('release' or 'raw')." 19 | required: false 20 | outputs: 21 | dart-version: 22 | description: 'The installed Dart version.' 23 | runs: 24 | using: "node20" 25 | main: "dist/index.mjs" 26 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:dart_flutter_team_lints/analysis_options.yaml 2 | 3 | linter: 4 | rules: 5 | - prefer_relative_imports 6 | -------------------------------------------------------------------------------- /dist/sig.txt: -------------------------------------------------------------------------------- 1 | 27f84f29568ea4f8e733983f9d71ff90 2 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Dart files 2 | .dart_tool/ 3 | pubspec.lock 4 | -------------------------------------------------------------------------------- /example/bin/main.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | void main(List args) { 6 | print('hello world'); 7 | } 8 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | publish_to: none 3 | 4 | environment: 5 | sdk: ">=2.12.0 <3.0.0" 6 | 7 | dev_dependencies: 8 | test: any 9 | -------------------------------------------------------------------------------- /example/test/example_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | test('true is true', () { 9 | expect(true, isTrue); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'dart:convert'; 6 | import 'dart:js_interop'; 7 | 8 | import 'package:path/path.dart' as path; 9 | import 'package:pub_semver/pub_semver.dart'; 10 | 11 | import 'node/actions/core.dart'; 12 | import 'node/actions/exec.dart'; 13 | import 'node/actions/http_client.dart'; 14 | import 'node/actions/tool_cache.dart'; 15 | import 'node/fs.dart'; 16 | import 'node/os.dart'; 17 | import 'node/process.dart'; 18 | 19 | void main(List args) async { 20 | try { 21 | await _impl(args); 22 | } catch (e) { 23 | _fail('$e'); 24 | } 25 | } 26 | 27 | Future _impl(List args) async { 28 | // sdk 29 | var sdk = core.getInput('sdk'); 30 | if (sdk.isEmpty) { 31 | sdk = 'stable'; 32 | } 33 | 34 | // A `3.0` in a workflow file reaches us as a `3` here; to work around that, 35 | // we promote any int value back to a double. 36 | if (int.tryParse(sdk) != null && !sdk.contains('.')) { 37 | // Convert a '3' to a '3.0'. 38 | sdk = '$sdk.0'; 39 | } 40 | 41 | // flavor 42 | var flavor = core.getInput('flavor'); 43 | if (flavor.isEmpty) { 44 | flavor = sdk == 'main' ? 'raw' : 'release'; 45 | } else if (flavor != 'raw' && flavor != 'release') { 46 | _fail("Unrecognized build flavor '$flavor'."); 47 | return; 48 | } 49 | final raw = flavor == 'raw'; 50 | 51 | // os 52 | final os = getPlatform(); 53 | 54 | // architecture 55 | var architecture = core.getInput('architecture'); 56 | if (architecture.isEmpty) { 57 | architecture = getArch(); 58 | } 59 | 60 | // calculate version and channel 61 | String version; 62 | String channel; 63 | 64 | if (sdk.split('.').length == 2) { 65 | // Handle the wildcard (`2.19`, `3.1`, ...) format. 66 | channel = 'stable'; 67 | 68 | // Find the latest version for the given sdk release. 69 | version = await findLatestSdkForRelease(sdk); 70 | } else if (sdk == 'stable' || sdk == 'beta' || sdk == 'dev') { 71 | channel = sdk; 72 | version = raw ? 'latest' : (await latestPublishedVersion(channel, flavor)); 73 | } else if (sdk == 'main') { 74 | channel = 'main'; 75 | version = 'latest'; 76 | } else { 77 | version = sdk; 78 | 79 | // Derive the channel from the version string. 80 | if (sdk.contains('dev')) { 81 | channel = 'dev'; 82 | } else if (sdk.contains('beta')) { 83 | channel = 'beta'; 84 | } else if (sdk.contains('main')) { 85 | _fail('Versions cannot be specified for main channel builds.'); 86 | return; 87 | } else { 88 | channel = 'stable'; 89 | } 90 | } 91 | 92 | core.info('Installing the $os-$architecture Dart SDK version $version from ' 93 | 'the $channel ($flavor) channel.'); 94 | 95 | // Calculate url based on https://dart.dev/tools/sdk/archive#download-urls. 96 | final url = 'https://storage.googleapis.com/dart-archive/' 97 | 'channels/$channel/$flavor/$version/sdk/' 98 | 'dartsdk-$os-$architecture-release.zip'; 99 | 100 | // Use a cached sdk or download and cache the sdk; using a 'raw' sdk flavor 101 | // disables caching. 102 | final toolName = raw ? 'dart_raw' : 'dart'; 103 | var sdkPath = !raw ? toolCache.find(toolName, version, architecture) : ''; 104 | if (sdkPath.isNotEmpty) { 105 | core.info('Using cached sdk from $sdkPath.'); 106 | } else { 107 | core.info('$url ...'); 108 | 109 | final archivePath = path.join( 110 | // `RUNNER_TEMP` variable is guaranteed to be present. 111 | // https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables 112 | process.env('RUNNER_TEMP')!, 113 | path.url.basename(url), 114 | ); 115 | await toolCache.downloadTool(url, archivePath).toDart; 116 | var extractedFolder = 117 | (await toolCache.extractZip(archivePath).toDart).toDart; 118 | extractedFolder = path.join(extractedFolder, 'dart-sdk'); 119 | 120 | sdkPath = (await toolCache 121 | .cacheDir(extractedFolder, toolName, version, architecture) 122 | .toDart) 123 | .toDart; 124 | } 125 | 126 | final pubCache = path.join( 127 | process.env(os == 'windows' ? 'USERPROFILE' : 'HOME')!, '.pub-cache'); 128 | 129 | core.exportVariable('DART_HOME', sdkPath); 130 | core.addPath(path.join(sdkPath, 'bin')); 131 | core.exportVariable('PUB_CACHE', pubCache); 132 | core.addPath(path.join(pubCache, 'bin')); 133 | 134 | // Create the OIDC token used for pub.dev publishing. 135 | await createPubOIDCToken(); 136 | 137 | // Configure the outputs. 138 | core.setOutput('dart-version', getVersionFromSdk(sdkPath)); 139 | 140 | // Report success; print version. 141 | await exec.exec('dart', ['--version'.toJS].toJS).toDart; 142 | } 143 | 144 | String getVersionFromSdk(String sdkPath) { 145 | final versionFilePath = path.join(sdkPath, 'version'); 146 | return fs.readFileSync(versionFilePath, 'utf8').trim(); 147 | } 148 | 149 | /// Returns 'x64', 'ia32', 'arm', or 'arm64'. 150 | String getArch() { 151 | const supported = ['x64', 'ia32', 'arm', 'arm64']; 152 | return supported.contains(os.arch) ? os.arch : 'x64'; 153 | } 154 | 155 | /// Returns 'linux', 'windows', or 'macos'. 156 | String getPlatform() { 157 | return switch (os.platform) { 158 | 'win32' => 'windows', 159 | 'darwin' => 'macos', 160 | _ => 'linux' 161 | }; 162 | } 163 | 164 | // When enabled through env variables, create an OIDC token for publishing on 165 | // pub.dev. 166 | Future createPubOIDCToken() async { 167 | final tokenRequestUrl = process.env('ACTIONS_ID_TOKEN_REQUEST_URL'); 168 | final tokenRequestToken = process.env('ACTIONS_ID_TOKEN_REQUEST_TOKEN'); 169 | 170 | if (tokenRequestUrl == null || tokenRequestToken == null) { 171 | return; 172 | } 173 | 174 | final token = (await core.getIDToken('https://pub.dev').toDart).toDart; 175 | 176 | core.exportVariable('PUB_TOKEN', token); 177 | 178 | await exec 179 | .exec( 180 | 'dart', 181 | [ 182 | 'pub'.toJS, 183 | 'token'.toJS, 184 | 'add'.toJS, 185 | 'https://pub.dev'.toJS, 186 | '--env-var'.toJS, 187 | 'PUB_TOKEN'.toJS, 188 | ].toJS) 189 | .toDart; 190 | } 191 | 192 | // https://storage.googleapis.com/dart-archive/channels/stable/release/latest/VERSION 193 | // { 194 | // "date": "2023-02-07", 195 | // "version": "2.19.2", 196 | // "revision": "e46b4f59490230778e907bde2eedb06b062d31be" 197 | // } 198 | 199 | // Query google storage for the most recent published SDK version for the given 200 | // channel and flavor. 201 | Future latestPublishedVersion(String channel, String flavor) async { 202 | final url = 'https://storage.googleapis.com/dart-archive/channels/' 203 | '$channel/$flavor/latest/VERSION'; 204 | 205 | final http = HttpClient( 206 | 'setup-dart', 207 | [].toJS, 208 | { 209 | 'allowRedirects': true, 210 | 'maxRedirects': 3, 211 | 'allowRetries': true, 212 | 'maxRetries': 3, 213 | }.jsify() as JSObject?, 214 | ); 215 | 216 | var response = (await http.get(url).toDart) as HttpClientResponse; 217 | var data = (await response.readBody().toDart).toDart; 218 | var json = (jsonDecode(data) as Map).cast(); 219 | return json['version'] as String; 220 | } 221 | 222 | /// Find the latest SDK patch version for the given SDK release. 223 | /// 224 | /// [sdkRelease] must be in the form of `major.minor` (e.g., `2.19`). 225 | Future findLatestSdkForRelease(String sdkRelease) async { 226 | final filePrefix = 'channels/stable/release/$sdkRelease.'; 227 | final url = 'https://storage.googleapis.com/storage/v1/b/dart-archive/o' 228 | '?prefix=$filePrefix&delimiter=/'; 229 | 230 | final http = HttpClient( 231 | 'setup-dart', 232 | [].toJS, 233 | { 234 | 'allowRedirects': true, 235 | 'maxRedirects': 3, 236 | 'allowRetries': true, 237 | 'maxRetries': 3, 238 | }.jsify() as JSObject?, 239 | ); 240 | 241 | // { 242 | // "kind": "storage#objects", 243 | // "prefixes": [ 244 | // "channels/stable/release/2.19.0/", 245 | // "channels/stable/release/2.19.1/", 246 | // ... 247 | // "channels/stable/release/2.19.6/" 248 | // ] 249 | // } 250 | var response = (await http.get(url).toDart) as HttpClientResponse; 251 | var data = (await response.readBody().toDart).toDart; 252 | var json = (jsonDecode(data) as Map).cast(); 253 | 254 | final paths = (json['prefixes'] as List).cast(); 255 | final versions = paths.map((p) => (p.split('/')..removeLast()).last).toList(); 256 | 257 | // Sort versions by semver and return the highest version. 258 | final semvers = versions.map(Version.parse).toList(); 259 | semvers.sort(); 260 | return semvers.last.toString(); 261 | } 262 | 263 | void _fail(String message) { 264 | // 'core.setFailed' throws when we call it; see #107. 265 | // core.setFailed(message); 266 | 267 | core.error(message); 268 | process.exitCode = 1; 269 | } 270 | -------------------------------------------------------------------------------- /lib/main.mjs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import * as core from '@actions/core'; 6 | import * as exec from '@actions/exec'; 7 | import * as httpClient from '@actions/http-client'; 8 | import * as toolCache from '@actions/tool-cache'; 9 | import * as fs from 'fs'; 10 | import * as module from 'module'; 11 | import * as os from 'os'; 12 | import process from 'process'; 13 | 14 | const require = module.createRequire(import.meta.url); 15 | 16 | // Setup properties for JS interop in Dart. 17 | 18 | globalThis.self = globalThis; 19 | globalThis.core = core; 20 | globalThis.exec = exec; 21 | globalThis.HttpClient = httpClient.HttpClient; 22 | globalThis.toolCache = toolCache; 23 | globalThis.fs = fs; 24 | globalThis.os = os; 25 | globalThis.process = process; 26 | globalThis.location = { href: `file://${process.cwd()}/`} 27 | 28 | globalThis.dartMainRunner = async function(main, args) { 29 | const dir = process.argv[2]; 30 | await main(dir); 31 | } 32 | 33 | async function scriptMain() { 34 | // We have to load `main.js` here so that the `dartMainRunner` hook is 35 | // registered before the IIFE in `dart_main.js` runs. 36 | require('../dist/main.cjs'); 37 | } 38 | 39 | if (require.main === require.module) { 40 | await scriptMain(); 41 | } 42 | -------------------------------------------------------------------------------- /lib/node/actions/core.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'dart:js_interop'; 6 | 7 | @JS() 8 | external Core get core; 9 | 10 | @JS() 11 | extension type Core(JSObject obj) { 12 | external String getInput(String name); 13 | 14 | external void setOutput(String name, String value); 15 | 16 | external void info(String name); 17 | external void warning(String name); 18 | external void error(String name); 19 | 20 | external void addPath(String element); 21 | 22 | external void exportVariable(String name, String value); 23 | 24 | external JSPromise getIDToken(String audience); 25 | } 26 | -------------------------------------------------------------------------------- /lib/node/actions/exec.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'dart:js_interop'; 6 | 7 | @JS() 8 | external Exec get exec; 9 | 10 | @JS() 11 | extension type Exec(JSObject obj) { 12 | /// Exec a command. 13 | /// 14 | /// Output will be streamed to the live console. Returns promise with return 15 | /// code. 16 | external JSPromise exec(String commandLine, [JSArray? args]); 17 | } 18 | -------------------------------------------------------------------------------- /lib/node/actions/http_client.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'dart:js_interop'; 6 | 7 | @JS() 8 | extension type HttpClient._(JSObject obj) { 9 | external HttpClient( 10 | String userAgent, [ 11 | JSArray? handlers, 12 | JSObject? requestOptions, 13 | ]); 14 | 15 | // JSPromise 16 | external JSPromise get(String requestUrl); 17 | external JSPromise getJson(String requestUrl); 18 | } 19 | 20 | @JS() 21 | extension type HttpClientResponse._(JSObject obj) { 22 | external JSPromise readBody(); 23 | } 24 | -------------------------------------------------------------------------------- /lib/node/actions/tool_cache.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'dart:js_interop'; 6 | 7 | @JS() 8 | external ToolCache get toolCache; 9 | 10 | @JS() 11 | extension type ToolCache(JSObject obj) { 12 | /// Finds the path to a tool version in the local installed tool cache. 13 | /// 14 | /// @param toolName name of the tool 15 | /// @param versionSpec version of the tool 16 | /// @param arch optional arch. defaults to arch of computer 17 | external String find( 18 | String toolName, 19 | String versionSpec, [ 20 | String? arch, 21 | ]); 22 | 23 | /// Download a tool from an url and stream it into a file. 24 | /// 25 | /// @param url url of tool to download 26 | /// @param dest path to download tool 27 | /// @returns path to downloaded tool 28 | external JSPromise downloadTool(String url, [String? dest]); 29 | 30 | /// Extract a zip. 31 | /// 32 | /// @param file path to the zip 33 | /// @returns path to the destination directory 34 | external JSPromise extractZip(String file); 35 | 36 | /// Caches a directory and installs it into the tool cacheDir 37 | /// 38 | /// @param sourceDir the directory to cache into tools 39 | /// @param tool tool name 40 | /// @param version version of the tool. semver format 41 | /// @param arch architecture of the tool. Optional. 42 | /// Defaults to machine architecture 43 | external JSPromise cacheDir( 44 | String sourceDir, 45 | String tool, 46 | String version, [ 47 | String? arch, 48 | ]); 49 | } 50 | -------------------------------------------------------------------------------- /lib/node/fs.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'dart:js_interop'; 6 | 7 | /// POSIX functions for interacting with the file system. 8 | /// Wraps https://nodejs.org/api/fs.html 9 | @JS() 10 | external FileSystem get fs; 11 | 12 | @JS() 13 | extension type FileSystem(JSObject fileSystem) { 14 | /// Whether the [path] exists, false otherwise. 15 | external bool existsSync(String path); 16 | 17 | /// Read the contents of the [path]. 18 | external String readFileSync(String path, [String encoding]); 19 | } 20 | -------------------------------------------------------------------------------- /lib/node/os.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'dart:js_interop'; 6 | 7 | /// Operating system-related utility methods and properties. 8 | /// Wraps https://nodejs.org/api/os.html 9 | @JS() 10 | external OS get os; 11 | 12 | @JS() 13 | extension type OS(JSObject obj) { 14 | @JS('arch') 15 | external String _arch(); 16 | 17 | /// The operating system CPU architecture. 18 | String get arch => _arch(); 19 | 20 | @JS('platform') 21 | external String _platform(); 22 | 23 | /// The operating system platform. 24 | String get platform => _platform(); 25 | } 26 | -------------------------------------------------------------------------------- /lib/node/process.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'dart:js_interop'; 6 | import 'dart:js_interop_unsafe'; 7 | 8 | /// Provides information about, and control over, the current Node.js process. 9 | /// Wraps https://nodejs.org/api/process.html 10 | @JS() 11 | external Process get process; 12 | 13 | @JS() 14 | extension type Process(JSObject obj) { 15 | @JS('env') 16 | // Map 17 | external JSObject get _env; 18 | 19 | /// Read the environment variable [variable]. 20 | String? env(String variable) { 21 | return _env.getProperty(variable.toJS)?.toDart; 22 | } 23 | 24 | external int exitCode; 25 | } 26 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "setup-dart", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "setup-dart", 9 | "version": "0.0.0", 10 | "license": "BSD", 11 | "dependencies": { 12 | "@actions/core": "^1.11.1", 13 | "@actions/exec": "^1.1.1", 14 | "@actions/http-client": "^2.2.3", 15 | "@actions/tool-cache": "^2.0.2" 16 | } 17 | }, 18 | "node_modules/@actions/core": { 19 | "version": "1.11.1", 20 | "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", 21 | "integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==", 22 | "license": "MIT", 23 | "dependencies": { 24 | "@actions/exec": "^1.1.1", 25 | "@actions/http-client": "^2.0.1" 26 | } 27 | }, 28 | "node_modules/@actions/exec": { 29 | "version": "1.1.1", 30 | "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz", 31 | "integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==", 32 | "license": "MIT", 33 | "dependencies": { 34 | "@actions/io": "^1.0.1" 35 | } 36 | }, 37 | "node_modules/@actions/http-client": { 38 | "version": "2.2.3", 39 | "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz", 40 | "integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==", 41 | "license": "MIT", 42 | "dependencies": { 43 | "tunnel": "^0.0.6", 44 | "undici": "^5.25.4" 45 | } 46 | }, 47 | "node_modules/@actions/io": { 48 | "version": "1.1.3", 49 | "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz", 50 | "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==", 51 | "license": "MIT" 52 | }, 53 | "node_modules/@actions/tool-cache": { 54 | "version": "2.0.2", 55 | "resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-2.0.2.tgz", 56 | "integrity": "sha512-fBhNNOWxuoLxztQebpOaWu6WeVmuwa77Z+DxIZ1B+OYvGkGQon6kTVg6Z32Cb13WCuw0szqonK+hh03mJV7Z6w==", 57 | "license": "MIT", 58 | "dependencies": { 59 | "@actions/core": "^1.11.1", 60 | "@actions/exec": "^1.0.0", 61 | "@actions/http-client": "^2.0.1", 62 | "@actions/io": "^1.1.1", 63 | "semver": "^6.1.0" 64 | } 65 | }, 66 | "node_modules/@fastify/busboy": { 67 | "version": "2.1.1", 68 | "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", 69 | "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", 70 | "license": "MIT", 71 | "engines": { 72 | "node": ">=14" 73 | } 74 | }, 75 | "node_modules/semver": { 76 | "version": "6.3.1", 77 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", 78 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", 79 | "license": "ISC", 80 | "bin": { 81 | "semver": "bin/semver.js" 82 | } 83 | }, 84 | "node_modules/tunnel": { 85 | "version": "0.0.6", 86 | "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", 87 | "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", 88 | "license": "MIT", 89 | "engines": { 90 | "node": ">=0.6.11 <=0.7.0 || >=0.7.3" 91 | } 92 | }, 93 | "node_modules/undici": { 94 | "version": "5.29.0", 95 | "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", 96 | "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", 97 | "license": "MIT", 98 | "dependencies": { 99 | "@fastify/busboy": "^2.0.0" 100 | }, 101 | "engines": { 102 | "node": ">=14.0" 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "setup-dart", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "The setup-dart GitHub Action - download and setup the Dart SDK.", 6 | "main": "lib/main.mjs", 7 | "scripts": { 8 | "build": "dart compile js -olib/main.js lib/main.dart && dart tool/sig.dart --generate", 9 | "dist": "ncc build lib/main.mjs && cp lib/main.js dist/main.cjs && cp lib/sig.txt dist/sig.txt", 10 | "all": "npm run build && npm run dist" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/dart-lang/setup-dart.git" 15 | }, 16 | "type": "module", 17 | "keywords": [ 18 | "actions", 19 | "dart", 20 | "setup" 21 | ], 22 | "license": "BSD", 23 | "dependencies": { 24 | "@actions/core": "^1.11.1", 25 | "@actions/exec": "^1.1.1", 26 | "@actions/http-client": "^2.2.3", 27 | "@actions/tool-cache": "^2.0.2" 28 | } 29 | } -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: setup_dart 2 | description: The setup-dart GitHub Action - download and setup the Dart SDK. 3 | 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ^3.3.0 8 | 9 | dependencies: 10 | path: ^1.8.0 11 | pub_semver: ^2.1.0 12 | 13 | dev_dependencies: 14 | args: ^2.4.0 15 | crypto: ^3.0.0 16 | dart_flutter_team_lints: ^3.0.0 17 | -------------------------------------------------------------------------------- /tool/sig.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | import 'dart:io'; 6 | 7 | import 'package:args/args.dart'; 8 | import 'package:crypto/crypto.dart'; 9 | 10 | void main(List args) { 11 | var argsParser = ArgParser() 12 | ..addFlag( 13 | 'generate', 14 | negatable: false, 15 | help: 'Generate the compilation signature to lib/sig.txt.', 16 | ) 17 | ..addFlag( 18 | 'verify', 19 | negatable: false, 20 | help: 'Verify the compilation signature against dist/sig.txt.', 21 | ); 22 | 23 | var argsResult = argsParser.parse(args); 24 | 25 | final generate = argsResult['generate'] as bool; 26 | final verify = argsResult['verify'] as bool; 27 | 28 | if (!generate && !verify) { 29 | print('Please specify one of --generate or --verify.\n'); 30 | print(argsParser.usage); 31 | exit(1); 32 | } 33 | 34 | var sig = calcSig(); 35 | 36 | if (generate) { 37 | File('lib/sig.txt').writeAsStringSync('$sig\n'); 38 | } else if (verify) { 39 | var existing = File('dist/sig.txt').readAsStringSync().trim(); 40 | if (existing != sig) { 41 | stderr.writeln( 42 | "Compilation artifacts not up-to-date; re-run 'npm run all'."); 43 | exit(1); 44 | } else { 45 | print('Compilation artifacts up-to-date.'); 46 | } 47 | } 48 | } 49 | 50 | String calcSig() { 51 | final bytes = []; 52 | for (var file in _files()) { 53 | bytes.addAll(file.readAsBytesSync()); 54 | } 55 | return md5.convert(bytes).toString(); 56 | } 57 | 58 | List _files() { 59 | // Collect lib/ Dart files. 60 | final files = Directory('lib') 61 | .listSync(recursive: true) 62 | .whereType() 63 | .where((file) => file.path.endsWith('.dart')) 64 | .toList(); 65 | files.add(File('pubspec.yaml')); 66 | files.sort((a, b) => a.path.toLowerCase().compareTo(b.path.toLowerCase())); 67 | 68 | return files; 69 | } 70 | --------------------------------------------------------------------------------