diff --git a/.github/actions/setup-dotnet/action.yml b/.github/actions/setup-dotnet/action.yml new file mode 100644 index 000000000..8a0f77d96 --- /dev/null +++ b/.github/actions/setup-dotnet/action.yml @@ -0,0 +1,24 @@ +name: Setup .NET +description: Install the .NET SDK pinned by global.json with a cached NuGet package directory. + +runs: + using: composite + steps: + - uses: actions/setup-dotnet@v5 + with: + global-json-file: global.json + cache: true + # Hash .props/.targets alongside .fsproj: not all versions are declared in + # project files. FSharp.Compiler.Service.fsproj interpolates + # $(SystemCollectionsImmutableVersion), $(FSharpCoreShippedPackageVersionValue) + # and others defined in .props, so bumping one of those changes the resolved + # package graph without touching any .fsproj — a .fsproj-only key would not move. + # + # obj/ is excluded because restore generates *.nuget.g.props/.targets there. + # They don't exist at this point in a clean CI job, but including them would + # make the key depend on whether the workspace had been built before. + cache-dependency-path: | + **/*.fsproj + **/*.props + **/*.targets + !**/obj/** diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 79c4ad43f..dec8fff10 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,9 +25,7 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Restore tools run: dotnet tool restore @@ -46,9 +44,7 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Restore project run: dotnet restore Fable.sln @@ -68,12 +64,19 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Setup Node.js environment uses: actions/setup-node@v7 + with: + cache: npm + # build.sh runs `npm install` in src/fable-standalone and + # src/fable-compiler-js too, each with its own committed lockfile, so + # hashing only the root package-lock.json would leave their tarballs + # out of the cache key. + cache-dependency-path: | + **/package-lock.json + !**/node_modules/** - name: Fable Tests - JavaScript (linux) if: matrix.platform == 'ubuntu-latest' @@ -92,12 +95,19 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Setup Node.js environment uses: actions/setup-node@v7 + with: + cache: npm + # build.sh runs `npm install` in src/fable-standalone and + # src/fable-compiler-js too, each with its own committed lockfile, so + # hashing only the root package-lock.json would leave their tarballs + # out of the cache key. + cache-dependency-path: | + **/package-lock.json + !**/node_modules/** - name: Fable Tests - TypeScript run: ./build.sh test typescript @@ -114,12 +124,19 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Setup Node.js environment uses: actions/setup-node@v7 + with: + cache: npm + # build.sh runs `npm install` in src/fable-standalone and + # src/fable-compiler-js too, each with its own committed lockfile, so + # hashing only the root package-lock.json would leave their tarballs + # out of the cache key. + cache-dependency-path: | + **/package-lock.json + !**/node_modules/** - name: Fable Tests run: ./build.sh test integration @@ -133,12 +150,19 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Setup Node.js environment uses: actions/setup-node@v7 + with: + cache: npm + # build.sh runs `npm install` in src/fable-standalone and + # src/fable-compiler-js too, each with its own committed lockfile, so + # hashing only the root package-lock.json would leave their tarballs + # out of the cache key. + cache-dependency-path: | + **/package-lock.json + !**/node_modules/** - name: Fable Tests run: ./build.sh test standalone @@ -158,9 +182,7 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 @@ -203,12 +225,19 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Setup Node.js environment uses: actions/setup-node@v7 + with: + cache: npm + # build.sh runs `npm install` in src/fable-standalone and + # src/fable-compiler-js too, each with its own committed lockfile, so + # hashing only the root package-lock.json would leave their tarballs + # out of the cache key. + cache-dependency-path: | + **/package-lock.json + !**/node_modules/** - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable @@ -230,9 +259,7 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Setup Dart SDK uses: dart-lang/setup-dart@v1 @@ -249,9 +276,7 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Setup Erlang/OTP uses: erlef/setup-beam@v1 @@ -281,9 +306,7 @@ jobs: - uses: actions/checkout@v7 - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json + uses: ./.github/actions/setup-dotnet - name: Restore tools run: dotnet tool restore