├── .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 | [](https://github.com/dart-lang/setup-dart/actions/workflows/build.yml)
2 | [](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 |
--------------------------------------------------------------------------------