@cypress/github-action 5.0.3 → 5.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # cypress-io/github-action [![renovate-app badge][renovate-badge]][renovate-bot] [![Action status](https://github.com/cypress-io/github-action/workflows/main/badge.svg?branch=master)](https://github.com/cypress-io/github-action/actions)
2
2
 
3
- > [GitHub Action](https://docs.github.com/en/actions) for running [Cypress](https://www.cypress.io) end-to-end tests. Includes NPM installation, custom caching and lots of configuration options.
3
+ > [GitHub Action](https://docs.github.com/en/actions) for running [Cypress](https://www.cypress.io) end-to-end and component tests. Includes NPM installation, custom caching and lots of configuration options.
4
4
 
5
5
  ## Examples
6
6
 
@@ -49,7 +49,7 @@ name: End-to-end tests
49
49
  on: [push]
50
50
  jobs:
51
51
  cypress-run:
52
- runs-on: ubuntu-20.04
52
+ runs-on: ubuntu-22.04
53
53
  steps:
54
54
  - name: Checkout
55
55
  uses: actions/checkout@v3
@@ -61,7 +61,7 @@ jobs:
61
61
 
62
62
  [![Basic example](https://github.com/cypress-io/github-action/workflows/example-basic/badge.svg?branch=master)](.github/workflows/example-basic.yml)
63
63
 
64
- The workflow file [.github/workflows/example-basic.yml](.github/workflows/example-basic.yml) shows how Cypress runs on GH Actions using Ubuntu (16, 18, or 20), on Windows, and on Mac without additional OS dependencies necessary.
64
+ The workflow file [.github/workflows/example-basic.yml](.github/workflows/example-basic.yml) shows how Cypress runs on GH Actions using Ubuntu (20 and 22), on Windows, and on Mac without additional OS dependencies necessary.
65
65
 
66
66
  **Note:** this package assumes that `cypress` is declared as a development dependency in the `package.json` file. The `cypress` NPM module is required to run Cypress via its [NPM module API](https://on.cypress.io/module-api).
67
67
 
@@ -94,7 +94,7 @@ name: E2E on Chrome
94
94
  on: [push]
95
95
  jobs:
96
96
  cypress-run:
97
- runs-on: ubuntu-20.04
97
+ runs-on: ubuntu-22.04
98
98
  # let's make sure our tests pass on Chrome browser
99
99
  name: E2E on Chrome
100
100
  steps:
@@ -115,9 +115,9 @@ name: Firefox
115
115
  on: push
116
116
  jobs:
117
117
  firefox:
118
- runs-on: ubuntu-latest
118
+ runs-on: ubuntu-22.04
119
119
  container:
120
- image: cypress/browsers:node12.16.1-chrome80-ff73
120
+ image: cypress/browsers:node18.12.0-chrome106-ff106
121
121
  options: --user 1001
122
122
  steps:
123
123
  - uses: actions/checkout@v3
@@ -147,8 +147,6 @@ jobs:
147
147
 
148
148
  [![Edge example](https://github.com/cypress-io/github-action/workflows/example-edge/badge.svg?branch=master)](.github/workflows/example-edge.yml)
149
149
 
150
- **Note:** Microsoft has not released Edge for Linux yet, thus you need to run these tests on Windows or Mac runners with Edge preinstalled. You can use [`cypress info`](https://on.cypress.io/command-line#cypress-info) command to see the browsers installed on the machine.
151
-
152
150
  ### Headed
153
151
 
154
152
  Run the browser in headed mode - as of Cypress v8.0 the `cypress run` command executes tests in `headless` mode by default
@@ -158,7 +156,7 @@ name: Chrome headed
158
156
  on: [push]
159
157
  jobs:
160
158
  cypress-run:
161
- runs-on: ubuntu-20.04
159
+ runs-on: ubuntu-22.04
162
160
  steps:
163
161
  - uses: actions/checkout@v3
164
162
  - uses: cypress-io/github-action@v5
@@ -176,10 +174,10 @@ name: E2E in custom container
176
174
  on: [push]
177
175
  jobs:
178
176
  cypress-run:
179
- runs-on: ubuntu-20.04
180
- # Cypress Docker image with Chrome v78
181
- # and Firefox v70 pre-installed
182
- container: cypress/browsers:node12.13.0-chrome78-ff70
177
+ runs-on: ubuntu-22.04
178
+ # Cypress Docker image with Chrome v106
179
+ # and Firefox v106 pre-installed
180
+ container: cypress/browsers:node18.12.0-chrome106-ff106
183
181
  steps:
184
182
  - uses: actions/checkout@v3
185
183
  - uses: cypress-io/github-action@v5
@@ -196,7 +194,7 @@ name: Cypress tests
196
194
  on: [push]
197
195
  jobs:
198
196
  cypress-run:
199
- runs-on: ubuntu-20.04
197
+ runs-on: ubuntu-22.04
200
198
  steps:
201
199
  - name: Checkout
202
200
  uses: actions/checkout@v3
@@ -214,7 +212,7 @@ name: Cypress tests
214
212
  on: [push]
215
213
  jobs:
216
214
  cypress-run:
217
- runs-on: ubuntu-20.04
215
+ runs-on: ubuntu-22.04
218
216
  steps:
219
217
  - name: Checkout
220
218
  uses: actions/checkout@v3
@@ -240,7 +238,7 @@ on: [push]
240
238
  jobs:
241
239
  cypress-run:
242
240
  name: Cypress run
243
- runs-on: ubuntu-20.04
241
+ runs-on: ubuntu-22.04
244
242
  steps:
245
243
  - name: Checkout
246
244
  uses: actions/checkout@v3
@@ -251,7 +249,7 @@ jobs:
251
249
  spec: cypress/integration/spec1.js
252
250
  ```
253
251
 
254
- You can pass multiple multiple specs and wild card patterns using multi-line parameter, see [example-config.yml](./.github/workflows/example-config.yml):
252
+ You can pass multiple specs and wild card patterns using multi-line parameter, see [example-config.yml](./.github/workflows/example-config.yml):
255
253
 
256
254
  ```yml
257
255
  spec: |
@@ -271,7 +269,7 @@ on: [push]
271
269
  jobs:
272
270
  cypress-run:
273
271
  name: Cypress run
274
- runs-on: ubuntu-20.04
272
+ runs-on: ubuntu-22.04
275
273
  steps:
276
274
  - name: Checkout
277
275
  uses: actions/checkout@v3
@@ -291,7 +289,7 @@ on: [push]
291
289
  jobs:
292
290
  cypress-run:
293
291
  name: Cypress run
294
- runs-on: ubuntu-20.04
292
+ runs-on: ubuntu-22.04
295
293
  steps:
296
294
  - name: Checkout
297
295
  uses: actions/checkout@v3
@@ -323,7 +321,7 @@ on: [push]
323
321
  jobs:
324
322
  cypress-run:
325
323
  name: Cypress run
326
- runs-on: ubuntu-20.04
324
+ runs-on: ubuntu-22.04
327
325
  steps:
328
326
  - name: Checkout
329
327
  uses: actions/checkout@v3
@@ -350,7 +348,7 @@ name: example-quiet
350
348
  on: [push]
351
349
  jobs:
352
350
  cypress-run:
353
- runs-on: ubuntu-latest
351
+ runs-on: ubuntu-22.04
354
352
  steps:
355
353
  - name: Checkout
356
354
  uses: actions/checkout@v3
@@ -374,11 +372,11 @@ name: tags
374
372
  on: [push]
375
373
  jobs:
376
374
  cypress-run:
377
- runs-on: ubuntu-latest
375
+ runs-on: ubuntu-22.04
378
376
  # let's make sure our "app" works on several versions of Node
379
377
  strategy:
380
378
  matrix:
381
- node: [10, 12]
379
+ node: [14, 16, 18]
382
380
  name: E2E on Node v${{ matrix.node }}
383
381
  steps:
384
382
  - name: Setup Node
@@ -415,7 +413,7 @@ name: Artifacts
415
413
  on: [push]
416
414
  jobs:
417
415
  cypress-run:
418
- runs-on: ubuntu-20.04
416
+ runs-on: ubuntu-22.04
419
417
  name: Artifacts
420
418
  steps:
421
419
  - uses: actions/checkout@v3
@@ -449,7 +447,7 @@ on: [push]
449
447
  jobs:
450
448
  cypress-run:
451
449
  name: Cypress run
452
- runs-on: ubuntu-20.04
450
+ runs-on: ubuntu-22.04
453
451
  steps:
454
452
  - name: Checkout
455
453
  uses: actions/checkout@v3
@@ -472,7 +470,7 @@ on: [push]
472
470
  jobs:
473
471
  cypress-run:
474
472
  name: Cypress run
475
- runs-on: ubuntu-20.04
473
+ runs-on: ubuntu-22.04
476
474
  steps:
477
475
  - name: Checkout
478
476
  uses: actions/checkout@v3
@@ -497,7 +495,7 @@ on: [push]
497
495
  jobs:
498
496
  test:
499
497
  name: Cypress run
500
- runs-on: ubuntu-20.04
498
+ runs-on: ubuntu-22.04
501
499
  strategy:
502
500
  # when one test fails, DO NOT cancel the other
503
501
  # containers, because this will kill Cypress processes
@@ -550,7 +548,7 @@ You can run [Cypress component tests](https://on.cypress.io/component-testing) i
550
548
  component: true
551
549
  ```
552
550
 
553
- See the example project [component-test](examples/v10/component-tests/) and the [example-component-test-workflow](.github/workflows/example-component-test.yml) for more details.
551
+ See the example project [component-test](examples/component-tests/) and the [example-component-test-workflow](.github/workflows/example-component-test.yml) for more details.
554
552
 
555
553
  ### Build app
556
554
 
@@ -561,7 +559,7 @@ name: Build
561
559
  on: [push]
562
560
  jobs:
563
561
  cypress-run:
564
- runs-on: ubuntu-20.04
562
+ runs-on: ubuntu-22.04
565
563
  steps:
566
564
  - name: Checkout
567
565
  uses: actions/checkout@v3
@@ -580,7 +578,7 @@ name: With server
580
578
  on: [push]
581
579
  jobs:
582
580
  cypress-run:
583
- runs-on: ubuntu-20.04
581
+ runs-on: ubuntu-22.04
584
582
  steps:
585
583
  - name: Checkout
586
584
  uses: actions/checkout@v3
@@ -597,7 +595,7 @@ name: With server
597
595
  on: [push]
598
596
  jobs:
599
597
  cypress-run:
600
- runs-on: ubuntu-20.04
598
+ runs-on: ubuntu-22.04
601
599
  steps:
602
600
  - name: Checkout
603
601
  uses: actions/checkout@v3
@@ -623,7 +621,7 @@ name: With servers
623
621
  on: [push]
624
622
  jobs:
625
623
  cypress-run:
626
- runs-on: ubuntu-18.04
624
+ runs-on: ubuntu-22.04
627
625
  steps:
628
626
  - name: Checkout
629
627
  uses: actions/checkout@v3
@@ -653,7 +651,7 @@ name: After server responds
653
651
  on: [push]
654
652
  jobs:
655
653
  cypress-run:
656
- runs-on: ubuntu-20.04
654
+ runs-on: ubuntu-22.04
657
655
  steps:
658
656
  - name: Checkout
659
657
  uses: actions/checkout@v3
@@ -728,7 +726,7 @@ name: Visual
728
726
  on: [push]
729
727
  jobs:
730
728
  e2e:
731
- runs-on: ubuntu-20.04
729
+ runs-on: ubuntu-22.04
732
730
  steps:
733
731
  - name: Checkout
734
732
  uses: actions/checkout@v3
@@ -743,8 +741,6 @@ jobs:
743
741
  command-prefix: 'percy exec -- npx'
744
742
  ```
745
743
 
746
- See live example [angular-pizza-creator](https://github.com/cypress-io/angular-pizza-creator).
747
-
748
744
  ### Custom test command
749
745
 
750
746
  You can overwrite the Cypress run command with your own
@@ -771,7 +767,7 @@ name: Parallel
771
767
  on: [push]
772
768
  jobs:
773
769
  test:
774
- runs-on: ubuntu-20.04
770
+ runs-on: ubuntu-22.04
775
771
  strategy:
776
772
  matrix:
777
773
  # run 3 copies of the current job in parallel
@@ -827,33 +823,67 @@ See the [example-custom-ci-build-id.yml](./.github/workflows/example-custom-ci-b
827
823
 
828
824
  ### Working directory
829
825
 
830
- In a monorepo, the end-to-end test might be placed in a different sub-folder from the application itself, like this
826
+ In a monorepo, the end-to-end or component test might be placed in a different sub-folder from the application itself.
827
+
828
+ Using a [Cypress legacy configuration](https://docs.cypress.io/guides/references/legacy-configuration) (Version 9 or earlier) the structure could look like this:
831
829
 
832
830
  ```text
833
831
  repo/
834
832
  app/
835
- e2e/
836
- cypress
833
+ app-test/
834
+ cypress/
835
+ fixtures/
836
+ integration/
837
+ plugins/
838
+ support/
837
839
  cypress.json
838
840
  package.json
839
841
  ```
840
842
 
841
- You can specify the `e2e` working directory when running Cypress tests using `working-directory` parameter
843
+ For End-to-End testing using a [Cypress configuration](https://docs.cypress.io/guides/references/configuration) for Version 10 and later, the structure could look like this :
844
+
845
+ ```text
846
+ repo/
847
+ app/
848
+ app-test/
849
+ cypress/
850
+ e2e/
851
+ fixtures/
852
+ support/
853
+ cypress.config.js
854
+ package.json
855
+ ```
856
+
857
+ Similarly for Component Testing with a [Cypress configuration](https://docs.cypress.io/guides/references/configuration) for Version 10 and later, the structure could look like this:
858
+
859
+ ```text
860
+ repo/
861
+ app/
862
+ app-test/
863
+ cypress/
864
+ component/
865
+ fixtures/
866
+ support/
867
+ cypress.config.js
868
+ package.json
869
+ ```
870
+
871
+ You can specify the `app-test` working directory when running Cypress tests using the `working-directory` parameter
842
872
 
843
873
  ```yml
844
874
  on: [push]
845
875
  jobs:
846
876
  cypress-run:
847
- runs-on: ubuntu-20.04
877
+ runs-on: ubuntu-22.04
848
878
  steps:
849
879
  - uses: actions/checkout@v3
850
880
  - uses: cypress-io/github-action@v5
851
881
  with:
852
882
  start: npm start
853
- working-directory: e2e
883
+ working-directory: app-test
854
884
  ```
855
885
 
856
- See [cypress-gh-action-monorepo](https://github.com/bahmutov/cypress-gh-action-monorepo) for a running example
886
+ See [example-basic.yml](.github/workflows/example-basic.yml) for an End-to-End test example and [example-component-test.yml](.github/workflows/example-component-test.yml) for a Component test example, using the parameter `working-directory`.
857
887
 
858
888
  ### Subfolders
859
889
 
@@ -880,7 +910,7 @@ name: E2E
880
910
  on: push
881
911
  jobs:
882
912
  test:
883
- runs-on: ubuntu-20.04
913
+ runs-on: ubuntu-22.04
884
914
  steps:
885
915
  - uses: actions/checkout@master
886
916
  - name: Install root dependencies
@@ -900,7 +930,7 @@ See [cypress-gh-action-subfolders](https://github.com/bahmutov/cypress-gh-action
900
930
 
901
931
  ### Yarn workspaces
902
932
 
903
- This action should discover Yarn workspace correctly. For example, see folder [examples/v10/start-and-yarn-workspaces](examples/v10/start-and-yarn-workspaces) and workflow file [example-start-and-yarn-workspaces.yml](.github/workflows/example-start-and-yarn-workspaces.yml)
933
+ This action should discover the Yarn workspaces correctly. For example, see folder [examples/start-and-yarn-workspaces](examples/start-and-yarn-workspaces) and workflow file [example-start-and-yarn-workspaces.yml](.github/workflows/example-start-and-yarn-workspaces.yml)
904
934
 
905
935
  ```yaml
906
936
  name: example-start-and-yarn-workspaces
@@ -910,12 +940,12 @@ jobs:
910
940
  # the example has Yarn workspace in its "root" folder
911
941
  # examples/start-and-yarn-workspaces
912
942
  # and tests in a subfolder like "workspace-1"
913
- runs-on: ubuntu-latest
943
+ runs-on: ubuntu-22.04
914
944
  steps:
915
945
  - uses: actions/checkout@v3
916
946
  - uses: cypress-io/github-action@v5
917
947
  with:
918
- working-directory: examples/v10/start-and-yarn-workspaces/workspace-1
948
+ working-directory: examples/start-and-yarn-workspaces/workspace-1
919
949
  build: yarn run build
920
950
  start: yarn start
921
951
  wait-on: 'http://localhost:5000'
@@ -932,11 +962,11 @@ name: End-to-end tests
932
962
  on: [push]
933
963
  jobs:
934
964
  cypress-run:
935
- runs-on: ubuntu-20.04
965
+ runs-on: ubuntu-22.04
936
966
  # let's make sure our "app" works on several versions of Node
937
967
  strategy:
938
968
  matrix:
939
- node: [10, 12]
969
+ node: [14, 16, 18]
940
970
  name: E2E on Node v${{ matrix.node }}
941
971
  steps:
942
972
  - name: Setup Node
@@ -967,10 +997,10 @@ name: Node versions
967
997
  on: [push]
968
998
  jobs:
969
999
  cypress-run:
970
- runs-on: ubuntu-latest
1000
+ runs-on: ubuntu-22.04
971
1001
  strategy:
972
1002
  matrix:
973
- node: [10, 12]
1003
+ node: [14, 16, 18]
974
1004
  name: E2E on Node v${{ matrix.node }}
975
1005
  steps:
976
1006
  - uses: actions/setup-node@v3
@@ -993,7 +1023,7 @@ name: E2E
993
1023
  on: push
994
1024
  jobs:
995
1025
  test:
996
- runs-on: ubuntu-20.04
1026
+ runs-on: ubuntu-22.04
997
1027
  steps:
998
1028
  - uses: actions/checkout@master
999
1029
  - name: Install dependencies
@@ -1046,7 +1076,7 @@ You can tell the CI to stop the job or the individual step if it runs for longer
1046
1076
  ```yml
1047
1077
  jobs:
1048
1078
  cypress-run:
1049
- runs-on: ubuntu-20.04
1079
+ runs-on: ubuntu-22.04
1050
1080
  # stop the job if it runs over 10 minutes
1051
1081
  # to prevent a hanging process from using all your CI minutes
1052
1082
  timeout-minutes: 10
@@ -1069,13 +1099,10 @@ Name | Description
1069
1099
  [cypress-gh-action-monorepo](https://github.com/bahmutov/cypress-gh-action-monorepo) | splits install and running tests commands, runs Cypress from sub-folder
1070
1100
  [cypress-gh-action-subfolders](https://github.com/bahmutov/cypress-gh-action-subfolders) | separate folder for Cypress dependencies
1071
1101
  [cypress-gh-action-split-install](https://github.com/bahmutov/cypress-gh-action-split-install) | only install NPM dependencies, then install and cache Cypress binary yourself
1072
- [cypress-gh-action-vue-example](https://github.com/cypress-io/cypress-gh-action-vue-example) | project was scaffolded using Vue CLI
1073
- [gh-action-and-gh-integration](https://github.com/cypress-io/gh-action-and-gh-integration) | records to the dashboard and has [Cypress GH Integration](https://on.cypress.io/github-integration) app installed
1074
1102
  [test-personal-site](https://github.com/bahmutov/test-personal-site) | Testing an external website every night and by manually clicking a button.
1075
1103
  [cypress-gh-action-changed-files](https://github.com/bahmutov/cypress-gh-action-changed-files) | Shows how to run different Cypress projects depending on changed files
1076
1104
  [cypress-examples](https://github.com/bahmutov/cypress-examples) | Shows separate install job from parallel test jobs
1077
1105
  [cypress-gh-action-split-jobs](https://github.com/bahmutov/cypress-gh-action-split-jobs) | Shows a separate install job with the build step, and another job that runs the tests
1078
- [cypress-and-jest-typescript-example](https://github.com/cypress-io/cypress-and-jest-typescript-example) | Run E2E and Jest unit tests in parallel
1079
1106
  [cypress-react-component-example](https://github.com/bahmutov/cypress-react-component-example) | Run E2E and component tests using this action
1080
1107
  <!-- prettier-ignore-end -->
1081
1108
 
@@ -1133,7 +1160,7 @@ $ node src/ping-cli.js <url>
1133
1160
  For example
1134
1161
 
1135
1162
  ```
1136
- $ node src/ping.js https://example.cypress.io
1163
+ $ node src/ping-cli.js https://example.cypress.io
1137
1164
  pinging url https://example.cypress.io for 30 seconds
1138
1165
  ::debug::pinging https://example.cypress.io has finished ok
1139
1166
  ```
@@ -1191,7 +1218,7 @@ name: included
1191
1218
  on: [push]
1192
1219
  jobs:
1193
1220
  cypress-run:
1194
- runs-on: ubuntu-latest
1221
+ runs-on: ubuntu-22.04
1195
1222
  # Docker image with Cypress pre-installed
1196
1223
  # https://github.com/cypress-io/cypress-docker-images/tree/master/included
1197
1224
  container: cypress/included:3.8.3
@@ -1211,7 +1238,7 @@ name: info
1211
1238
  on: [push]
1212
1239
  jobs:
1213
1240
  cypress-run:
1214
- runs-on: ubuntu-20.04
1241
+ runs-on: ubuntu-22.04
1215
1242
  steps:
1216
1243
  - name: Checkout
1217
1244
  uses: actions/checkout@v3
@@ -1228,7 +1255,7 @@ name: info
1228
1255
  on: [push]
1229
1256
  jobs:
1230
1257
  cypress-run:
1231
- runs-on: ubuntu-20.04
1258
+ runs-on: ubuntu-22.04
1232
1259
  steps:
1233
1260
  - name: Checkout
1234
1261
  uses: actions/checkout@v3
@@ -1259,7 +1286,7 @@ on:
1259
1286
  - cron: '0 4 * * *'
1260
1287
  jobs:
1261
1288
  nightly:
1262
- runs-on: ubuntu-20.04
1289
+ runs-on: ubuntu-22.04
1263
1290
  steps:
1264
1291
  - name: Checkout
1265
1292
  uses: actions/checkout@v3
package/action.yml CHANGED
@@ -30,7 +30,7 @@ inputs:
30
30
  description: 'A different start command on Windows'
31
31
  required: false
32
32
  build:
33
- description: 'Command to run in build step before starting tests'
33
+ description: 'Command to run build step before starting tests'
34
34
  required: false
35
35
  install:
36
36
  description: 'Whether or not to run install'
package/dist/index.js CHANGED
@@ -74,9 +74,10 @@ exports.isFeatureAvailable = isFeatureAvailable;
74
74
  * @param primaryKey an explicit key for restoring the cache
75
75
  * @param restoreKeys an optional ordered list of keys to use for restoring the cache if no cache hit occurred for key
76
76
  * @param downloadOptions cache download options
77
+ * @param enableCrossOsArchive an optional boolean enabled to restore on windows any cache created on any platform
77
78
  * @returns string returns the key for the cache hit, otherwise returns undefined
78
79
  */
79
- function restoreCache(paths, primaryKey, restoreKeys, options) {
80
+ function restoreCache(paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
80
81
  return __awaiter(this, void 0, void 0, function* () {
81
82
  checkPaths(paths);
82
83
  restoreKeys = restoreKeys || [];
@@ -94,7 +95,8 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
94
95
  try {
95
96
  // path are needed to compute version
96
97
  const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
97
- compressionMethod
98
+ compressionMethod,
99
+ enableCrossOsArchive
98
100
  });
99
101
  if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
100
102
  // Cache not found
@@ -141,10 +143,11 @@ exports.restoreCache = restoreCache;
141
143
  *
142
144
  * @param paths a list of file paths to be cached
143
145
  * @param key an explicit key for restoring the cache
146
+ * @param enableCrossOsArchive an optional boolean enabled to save cache on windows which could be restored on any platform
144
147
  * @param options cache upload options
145
148
  * @returns number returns cacheId if the cache was saved successfully and throws an error if save fails
146
149
  */
147
- function saveCache(paths, key, options) {
150
+ function saveCache(paths, key, options, enableCrossOsArchive = false) {
148
151
  var _a, _b, _c, _d, _e;
149
152
  return __awaiter(this, void 0, void 0, function* () {
150
153
  checkPaths(paths);
@@ -175,6 +178,7 @@ function saveCache(paths, key, options) {
175
178
  core.debug('Reserving Cache');
176
179
  const reserveCacheResponse = yield cacheHttpClient.reserveCache(key, paths, {
177
180
  compressionMethod,
181
+ enableCrossOsArchive,
178
182
  cacheSize: archiveFileSize
179
183
  });
180
184
  if ((_a = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.result) === null || _a === void 0 ? void 0 : _a.cacheId) {
@@ -247,7 +251,6 @@ const crypto = __importStar(__nccwpck_require__(6113));
247
251
  const fs = __importStar(__nccwpck_require__(7147));
248
252
  const url_1 = __nccwpck_require__(7310);
249
253
  const utils = __importStar(__nccwpck_require__(1518));
250
- const constants_1 = __nccwpck_require__(8840);
251
254
  const downloadUtils_1 = __nccwpck_require__(5500);
252
255
  const options_1 = __nccwpck_require__(6215);
253
256
  const requestUtils_1 = __nccwpck_require__(3981);
@@ -277,10 +280,17 @@ function createHttpClient() {
277
280
  const bearerCredentialHandler = new auth_1.BearerCredentialHandler(token);
278
281
  return new http_client_1.HttpClient('actions/cache', [bearerCredentialHandler], getRequestOptions());
279
282
  }
280
- function getCacheVersion(paths, compressionMethod) {
281
- const components = paths.concat(!compressionMethod || compressionMethod === constants_1.CompressionMethod.Gzip
282
- ? []
283
- : [compressionMethod]);
283
+ function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false) {
284
+ const components = paths;
285
+ // Add compression method to cache version to restore
286
+ // compressed cache as per compression method
287
+ if (compressionMethod) {
288
+ components.push(compressionMethod);
289
+ }
290
+ // Only check for windows platforms if enableCrossOsArchive is false
291
+ if (process.platform === 'win32' && !enableCrossOsArchive) {
292
+ components.push('windows-only');
293
+ }
284
294
  // Add salt to cache version to support breaking changes in cache entry
285
295
  components.push(versionSalt);
286
296
  return crypto
@@ -292,10 +302,15 @@ exports.getCacheVersion = getCacheVersion;
292
302
  function getCacheEntry(keys, paths, options) {
293
303
  return __awaiter(this, void 0, void 0, function* () {
294
304
  const httpClient = createHttpClient();
295
- const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod);
305
+ const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod, options === null || options === void 0 ? void 0 : options.enableCrossOsArchive);
296
306
  const resource = `cache?keys=${encodeURIComponent(keys.join(','))}&version=${version}`;
297
307
  const response = yield requestUtils_1.retryTypedResponse('getCacheEntry', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
308
+ // Cache not found
298
309
  if (response.statusCode === 204) {
310
+ // List cache for primary key only if cache miss occurs
311
+ if (core.isDebug()) {
312
+ yield printCachesListForDiagnostics(keys[0], httpClient, version);
313
+ }
299
314
  return null;
300
315
  }
301
316
  if (!requestUtils_1.isSuccessStatusCode(response.statusCode)) {
@@ -304,6 +319,7 @@ function getCacheEntry(keys, paths, options) {
304
319
  const cacheResult = response.result;
305
320
  const cacheDownloadUrl = cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.archiveLocation;
306
321
  if (!cacheDownloadUrl) {
322
+ // Cache achiveLocation not found. This should never happen, and hence bail out.
307
323
  throw new Error('Cache not found.');
308
324
  }
309
325
  core.setSecret(cacheDownloadUrl);
@@ -313,6 +329,22 @@ function getCacheEntry(keys, paths, options) {
313
329
  });
314
330
  }
315
331
  exports.getCacheEntry = getCacheEntry;
332
+ function printCachesListForDiagnostics(key, httpClient, version) {
333
+ return __awaiter(this, void 0, void 0, function* () {
334
+ const resource = `caches?key=${encodeURIComponent(key)}`;
335
+ const response = yield requestUtils_1.retryTypedResponse('listCache', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); }));
336
+ if (response.statusCode === 200) {
337
+ const cacheListResult = response.result;
338
+ const totalCount = cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.totalCount;
339
+ if (totalCount && totalCount > 0) {
340
+ core.debug(`No matching cache found for cache key '${key}', version '${version} and scope ${process.env['GITHUB_REF']}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key \nOther caches with similar key:`);
341
+ for (const cacheEntry of (cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.artifactCaches) || []) {
342
+ core.debug(`Cache Key: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheKey}, Cache Version: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheVersion}, Cache Scope: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.scope}, Cache Created: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.creationTime}`);
343
+ }
344
+ }
345
+ }
346
+ });
347
+ }
316
348
  function downloadCache(archiveLocation, archivePath, options) {
317
349
  return __awaiter(this, void 0, void 0, function* () {
318
350
  const archiveUrl = new url_1.URL(archiveLocation);
@@ -333,7 +365,7 @@ exports.downloadCache = downloadCache;
333
365
  function reserveCache(key, paths, options) {
334
366
  return __awaiter(this, void 0, void 0, function* () {
335
367
  const httpClient = createHttpClient();
336
- const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod);
368
+ const version = getCacheVersion(paths, options === null || options === void 0 ? void 0 : options.compressionMethod, options === null || options === void 0 ? void 0 : options.enableCrossOsArchive);
337
369
  const reserveCacheRequest = {
338
370
  key,
339
371
  version,
@@ -576,10 +608,6 @@ function getVersion(app) {
576
608
  // Use zstandard if possible to maximize cache performance
577
609
  function getCompressionMethod() {
578
610
  return __awaiter(this, void 0, void 0, function* () {
579
- if (process.platform === 'win32' && !(yield isGnuTarInstalled())) {
580
- // Disable zstd due to bug https://github.com/actions/cache/issues/301
581
- return constants_1.CompressionMethod.Gzip;
582
- }
583
611
  const versionOutput = yield getVersion('zstd');
584
612
  const version = semver.clean(versionOutput);
585
613
  if (!versionOutput.toLowerCase().includes('zstd command line interface')) {
@@ -603,13 +631,16 @@ function getCacheFileName(compressionMethod) {
603
631
  : constants_1.CacheFilename.Zstd;
604
632
  }
605
633
  exports.getCacheFileName = getCacheFileName;
606
- function isGnuTarInstalled() {
634
+ function getGnuTarPathOnWindows() {
607
635
  return __awaiter(this, void 0, void 0, function* () {
636
+ if (fs.existsSync(constants_1.GnuTarPathOnWindows)) {
637
+ return constants_1.GnuTarPathOnWindows;
638
+ }
608
639
  const versionOutput = yield getVersion('tar');
609
- return versionOutput.toLowerCase().includes('gnu tar');
640
+ return versionOutput.toLowerCase().includes('gnu tar') ? io.which('tar') : '';
610
641
  });
611
642
  }
612
- exports.isGnuTarInstalled = isGnuTarInstalled;
643
+ exports.getGnuTarPathOnWindows = getGnuTarPathOnWindows;
613
644
  function assertDefined(name, value) {
614
645
  if (value === undefined) {
615
646
  throw Error(`Expected ${name} but value was undefiend`);
@@ -645,6 +676,11 @@ var CompressionMethod;
645
676
  CompressionMethod["ZstdWithoutLong"] = "zstd-without-long";
646
677
  CompressionMethod["Zstd"] = "zstd";
647
678
  })(CompressionMethod = exports.CompressionMethod || (exports.CompressionMethod = {}));
679
+ var ArchiveToolType;
680
+ (function (ArchiveToolType) {
681
+ ArchiveToolType["GNU"] = "gnu";
682
+ ArchiveToolType["BSD"] = "bsd";
683
+ })(ArchiveToolType = exports.ArchiveToolType || (exports.ArchiveToolType = {}));
648
684
  // The default number of retry attempts.
649
685
  exports.DefaultRetryAttempts = 2;
650
686
  // The default delay in milliseconds between retry attempts.
@@ -653,6 +689,12 @@ exports.DefaultRetryDelay = 5000;
653
689
  // over the socket during this period, the socket is destroyed and the download
654
690
  // is aborted.
655
691
  exports.SocketTimeout = 5000;
692
+ // The default path of GNUtar on hosted Windows runners
693
+ exports.GnuTarPathOnWindows = `${process.env['PROGRAMFILES']}\\Git\\usr\\bin\\tar.exe`;
694
+ // The default path of BSDtar on hosted Windows runners
695
+ exports.SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32\\tar.exe`;
696
+ exports.TarFilename = 'cache.tar';
697
+ exports.ManifestFilename = 'manifest.txt';
656
698
  //# sourceMappingURL=constants.js.map
657
699
 
658
700
  /***/ }),
@@ -1065,27 +1107,27 @@ var __importStar = (this && this.__importStar) || function (mod) {
1065
1107
  };
1066
1108
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1067
1109
  const exec_1 = __nccwpck_require__(1514);
1110
+ const core_1 = __nccwpck_require__(2186);
1068
1111
  const io = __importStar(__nccwpck_require__(7436));
1069
1112
  const fs_1 = __nccwpck_require__(7147);
1070
1113
  const path = __importStar(__nccwpck_require__(1017));
1071
1114
  const utils = __importStar(__nccwpck_require__(1518));
1072
1115
  const constants_1 = __nccwpck_require__(8840);
1073
1116
  const IS_WINDOWS = process.platform === 'win32';
1074
- function getTarPath(args, compressionMethod) {
1117
+ core_1.exportVariable('MSYS', 'winsymlinks:nativestrict');
1118
+ // Returns tar path and type: BSD or GNU
1119
+ function getTarPath() {
1075
1120
  return __awaiter(this, void 0, void 0, function* () {
1076
1121
  switch (process.platform) {
1077
1122
  case 'win32': {
1078
- const systemTar = `${process.env['windir']}\\System32\\tar.exe`;
1079
- if (compressionMethod !== constants_1.CompressionMethod.Gzip) {
1080
- // We only use zstandard compression on windows when gnu tar is installed due to
1081
- // a bug with compressing large files with bsdtar + zstd
1082
- args.push('--force-local');
1123
+ const gnuTar = yield utils.getGnuTarPathOnWindows();
1124
+ const systemTar = constants_1.SystemTarPathOnWindows;
1125
+ if (gnuTar) {
1126
+ // Use GNUtar as default on windows
1127
+ return { path: gnuTar, type: constants_1.ArchiveToolType.GNU };
1083
1128
  }
1084
1129
  else if (fs_1.existsSync(systemTar)) {
1085
- return systemTar;
1086
- }
1087
- else if (yield utils.isGnuTarInstalled()) {
1088
- args.push('--force-local');
1130
+ return { path: systemTar, type: constants_1.ArchiveToolType.BSD };
1089
1131
  }
1090
1132
  break;
1091
1133
  }
@@ -1093,25 +1135,92 @@ function getTarPath(args, compressionMethod) {
1093
1135
  const gnuTar = yield io.which('gtar', false);
1094
1136
  if (gnuTar) {
1095
1137
  // fix permission denied errors when extracting BSD tar archive with GNU tar - https://github.com/actions/cache/issues/527
1096
- args.push('--delay-directory-restore');
1097
- return gnuTar;
1138
+ return { path: gnuTar, type: constants_1.ArchiveToolType.GNU };
1139
+ }
1140
+ else {
1141
+ return {
1142
+ path: yield io.which('tar', true),
1143
+ type: constants_1.ArchiveToolType.BSD
1144
+ };
1098
1145
  }
1099
- break;
1100
1146
  }
1101
1147
  default:
1102
1148
  break;
1103
1149
  }
1104
- return yield io.which('tar', true);
1150
+ // Default assumption is GNU tar is present in path
1151
+ return {
1152
+ path: yield io.which('tar', true),
1153
+ type: constants_1.ArchiveToolType.GNU
1154
+ };
1105
1155
  });
1106
1156
  }
1107
- function execTar(args, compressionMethod, cwd) {
1157
+ // Return arguments for tar as per tarPath, compressionMethod, method type and os
1158
+ function getTarArgs(tarPath, compressionMethod, type, archivePath = '') {
1108
1159
  return __awaiter(this, void 0, void 0, function* () {
1109
- try {
1110
- yield exec_1.exec(`"${yield getTarPath(args, compressionMethod)}"`, args, { cwd });
1160
+ const args = [`"${tarPath.path}"`];
1161
+ const cacheFileName = utils.getCacheFileName(compressionMethod);
1162
+ const tarFile = 'cache.tar';
1163
+ const workingDirectory = getWorkingDirectory();
1164
+ // Speficic args for BSD tar on windows for workaround
1165
+ const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
1166
+ compressionMethod !== constants_1.CompressionMethod.Gzip &&
1167
+ IS_WINDOWS;
1168
+ // Method specific args
1169
+ switch (type) {
1170
+ case 'create':
1171
+ args.push('--posix', '-cf', BSD_TAR_ZSTD
1172
+ ? tarFile
1173
+ : cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--exclude', BSD_TAR_ZSTD
1174
+ ? tarFile
1175
+ : cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--files-from', constants_1.ManifestFilename);
1176
+ break;
1177
+ case 'extract':
1178
+ args.push('-xf', BSD_TAR_ZSTD
1179
+ ? tarFile
1180
+ : archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'));
1181
+ break;
1182
+ case 'list':
1183
+ args.push('-tf', BSD_TAR_ZSTD
1184
+ ? tarFile
1185
+ : archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P');
1186
+ break;
1111
1187
  }
1112
- catch (error) {
1113
- throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
1188
+ // Platform specific args
1189
+ if (tarPath.type === constants_1.ArchiveToolType.GNU) {
1190
+ switch (process.platform) {
1191
+ case 'win32':
1192
+ args.push('--force-local');
1193
+ break;
1194
+ case 'darwin':
1195
+ args.push('--delay-directory-restore');
1196
+ break;
1197
+ }
1114
1198
  }
1199
+ return args;
1200
+ });
1201
+ }
1202
+ // Returns commands to run tar and compression program
1203
+ function getCommands(compressionMethod, type, archivePath = '') {
1204
+ return __awaiter(this, void 0, void 0, function* () {
1205
+ let args;
1206
+ const tarPath = yield getTarPath();
1207
+ const tarArgs = yield getTarArgs(tarPath, compressionMethod, type, archivePath);
1208
+ const compressionArgs = type !== 'create'
1209
+ ? yield getDecompressionProgram(tarPath, compressionMethod, archivePath)
1210
+ : yield getCompressionProgram(tarPath, compressionMethod);
1211
+ const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
1212
+ compressionMethod !== constants_1.CompressionMethod.Gzip &&
1213
+ IS_WINDOWS;
1214
+ if (BSD_TAR_ZSTD && type !== 'create') {
1215
+ args = [[...compressionArgs].join(' '), [...tarArgs].join(' ')];
1216
+ }
1217
+ else {
1218
+ args = [[...tarArgs].join(' '), [...compressionArgs].join(' ')];
1219
+ }
1220
+ if (BSD_TAR_ZSTD) {
1221
+ return args;
1222
+ }
1223
+ return [args.join(' ')];
1115
1224
  });
1116
1225
  }
1117
1226
  function getWorkingDirectory() {
@@ -1119,91 +1228,116 @@ function getWorkingDirectory() {
1119
1228
  return (_a = process.env['GITHUB_WORKSPACE']) !== null && _a !== void 0 ? _a : process.cwd();
1120
1229
  }
1121
1230
  // Common function for extractTar and listTar to get the compression method
1122
- function getCompressionProgram(compressionMethod) {
1123
- // -d: Decompress.
1124
- // unzstd is equivalent to 'zstd -d'
1125
- // --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
1126
- // Using 30 here because we also support 32-bit self-hosted runners.
1127
- switch (compressionMethod) {
1128
- case constants_1.CompressionMethod.Zstd:
1129
- return [
1130
- '--use-compress-program',
1131
- IS_WINDOWS ? 'zstd -d --long=30' : 'unzstd --long=30'
1132
- ];
1133
- case constants_1.CompressionMethod.ZstdWithoutLong:
1134
- return ['--use-compress-program', IS_WINDOWS ? 'zstd -d' : 'unzstd'];
1135
- default:
1136
- return ['-z'];
1137
- }
1231
+ function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
1232
+ return __awaiter(this, void 0, void 0, function* () {
1233
+ // -d: Decompress.
1234
+ // unzstd is equivalent to 'zstd -d'
1235
+ // --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
1236
+ // Using 30 here because we also support 32-bit self-hosted runners.
1237
+ const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
1238
+ compressionMethod !== constants_1.CompressionMethod.Gzip &&
1239
+ IS_WINDOWS;
1240
+ switch (compressionMethod) {
1241
+ case constants_1.CompressionMethod.Zstd:
1242
+ return BSD_TAR_ZSTD
1243
+ ? [
1244
+ 'zstd -d --long=30 --force -o',
1245
+ constants_1.TarFilename,
1246
+ archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
1247
+ ]
1248
+ : [
1249
+ '--use-compress-program',
1250
+ IS_WINDOWS ? '"zstd -d --long=30"' : 'unzstd --long=30'
1251
+ ];
1252
+ case constants_1.CompressionMethod.ZstdWithoutLong:
1253
+ return BSD_TAR_ZSTD
1254
+ ? [
1255
+ 'zstd -d --force -o',
1256
+ constants_1.TarFilename,
1257
+ archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
1258
+ ]
1259
+ : ['--use-compress-program', IS_WINDOWS ? '"zstd -d"' : 'unzstd'];
1260
+ default:
1261
+ return ['-z'];
1262
+ }
1263
+ });
1264
+ }
1265
+ // Used for creating the archive
1266
+ // -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
1267
+ // zstdmt is equivalent to 'zstd -T0'
1268
+ // --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
1269
+ // Using 30 here because we also support 32-bit self-hosted runners.
1270
+ // Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
1271
+ function getCompressionProgram(tarPath, compressionMethod) {
1272
+ return __awaiter(this, void 0, void 0, function* () {
1273
+ const cacheFileName = utils.getCacheFileName(compressionMethod);
1274
+ const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD &&
1275
+ compressionMethod !== constants_1.CompressionMethod.Gzip &&
1276
+ IS_WINDOWS;
1277
+ switch (compressionMethod) {
1278
+ case constants_1.CompressionMethod.Zstd:
1279
+ return BSD_TAR_ZSTD
1280
+ ? [
1281
+ 'zstd -T0 --long=30 --force -o',
1282
+ cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
1283
+ constants_1.TarFilename
1284
+ ]
1285
+ : [
1286
+ '--use-compress-program',
1287
+ IS_WINDOWS ? '"zstd -T0 --long=30"' : 'zstdmt --long=30'
1288
+ ];
1289
+ case constants_1.CompressionMethod.ZstdWithoutLong:
1290
+ return BSD_TAR_ZSTD
1291
+ ? [
1292
+ 'zstd -T0 --force -o',
1293
+ cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
1294
+ constants_1.TarFilename
1295
+ ]
1296
+ : ['--use-compress-program', IS_WINDOWS ? '"zstd -T0"' : 'zstdmt'];
1297
+ default:
1298
+ return ['-z'];
1299
+ }
1300
+ });
1138
1301
  }
1302
+ // Executes all commands as separate processes
1303
+ function execCommands(commands, cwd) {
1304
+ return __awaiter(this, void 0, void 0, function* () {
1305
+ for (const command of commands) {
1306
+ try {
1307
+ yield exec_1.exec(command, undefined, { cwd });
1308
+ }
1309
+ catch (error) {
1310
+ throw new Error(`${command.split(' ')[0]} failed with error: ${error === null || error === void 0 ? void 0 : error.message}`);
1311
+ }
1312
+ }
1313
+ });
1314
+ }
1315
+ // List the contents of a tar
1139
1316
  function listTar(archivePath, compressionMethod) {
1140
1317
  return __awaiter(this, void 0, void 0, function* () {
1141
- const args = [
1142
- ...getCompressionProgram(compressionMethod),
1143
- '-tf',
1144
- archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
1145
- '-P'
1146
- ];
1147
- yield execTar(args, compressionMethod);
1318
+ const commands = yield getCommands(compressionMethod, 'list', archivePath);
1319
+ yield execCommands(commands);
1148
1320
  });
1149
1321
  }
1150
1322
  exports.listTar = listTar;
1323
+ // Extract a tar
1151
1324
  function extractTar(archivePath, compressionMethod) {
1152
1325
  return __awaiter(this, void 0, void 0, function* () {
1153
1326
  // Create directory to extract tar into
1154
1327
  const workingDirectory = getWorkingDirectory();
1155
1328
  yield io.mkdirP(workingDirectory);
1156
- const args = [
1157
- ...getCompressionProgram(compressionMethod),
1158
- '-xf',
1159
- archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
1160
- '-P',
1161
- '-C',
1162
- workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
1163
- ];
1164
- yield execTar(args, compressionMethod);
1329
+ const commands = yield getCommands(compressionMethod, 'extract', archivePath);
1330
+ yield execCommands(commands);
1165
1331
  });
1166
1332
  }
1167
1333
  exports.extractTar = extractTar;
1334
+ // Create a tar
1168
1335
  function createTar(archiveFolder, sourceDirectories, compressionMethod) {
1169
1336
  return __awaiter(this, void 0, void 0, function* () {
1170
1337
  // Write source directories to manifest.txt to avoid command length limits
1171
- const manifestFilename = 'manifest.txt';
1172
- const cacheFileName = utils.getCacheFileName(compressionMethod);
1173
- fs_1.writeFileSync(path.join(archiveFolder, manifestFilename), sourceDirectories.join('\n'));
1174
- const workingDirectory = getWorkingDirectory();
1175
- // -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores.
1176
- // zstdmt is equivalent to 'zstd -T0'
1177
- // --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit.
1178
- // Using 30 here because we also support 32-bit self-hosted runners.
1179
- // Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd.
1180
- function getCompressionProgram() {
1181
- switch (compressionMethod) {
1182
- case constants_1.CompressionMethod.Zstd:
1183
- return [
1184
- '--use-compress-program',
1185
- IS_WINDOWS ? 'zstd -T0 --long=30' : 'zstdmt --long=30'
1186
- ];
1187
- case constants_1.CompressionMethod.ZstdWithoutLong:
1188
- return ['--use-compress-program', IS_WINDOWS ? 'zstd -T0' : 'zstdmt'];
1189
- default:
1190
- return ['-z'];
1191
- }
1192
- }
1193
- const args = [
1194
- '--posix',
1195
- ...getCompressionProgram(),
1196
- '-cf',
1197
- cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
1198
- '--exclude',
1199
- cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
1200
- '-P',
1201
- '-C',
1202
- workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
1203
- '--files-from',
1204
- manifestFilename
1205
- ];
1206
- yield execTar(args, compressionMethod, archiveFolder);
1338
+ fs_1.writeFileSync(path.join(archiveFolder, constants_1.ManifestFilename), sourceDirectories.join('\n'));
1339
+ const commands = yield getCommands(compressionMethod, 'create');
1340
+ yield execCommands(commands, archiveFolder);
1207
1341
  });
1208
1342
  }
1209
1343
  exports.createTar = createTar;
@@ -43042,45 +43176,8 @@ var request = __nccwpck_require__(6234);
43042
43176
  var graphql = __nccwpck_require__(8467);
43043
43177
  var authToken = __nccwpck_require__(334);
43044
43178
 
43045
- function _objectWithoutPropertiesLoose(source, excluded) {
43046
- if (source == null) return {};
43047
- var target = {};
43048
- var sourceKeys = Object.keys(source);
43049
- var key, i;
43050
-
43051
- for (i = 0; i < sourceKeys.length; i++) {
43052
- key = sourceKeys[i];
43053
- if (excluded.indexOf(key) >= 0) continue;
43054
- target[key] = source[key];
43055
- }
43056
-
43057
- return target;
43058
- }
43059
-
43060
- function _objectWithoutProperties(source, excluded) {
43061
- if (source == null) return {};
43179
+ const VERSION = "4.2.0";
43062
43180
 
43063
- var target = _objectWithoutPropertiesLoose(source, excluded);
43064
-
43065
- var key, i;
43066
-
43067
- if (Object.getOwnPropertySymbols) {
43068
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
43069
-
43070
- for (i = 0; i < sourceSymbolKeys.length; i++) {
43071
- key = sourceSymbolKeys[i];
43072
- if (excluded.indexOf(key) >= 0) continue;
43073
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
43074
- target[key] = source[key];
43075
- }
43076
- }
43077
-
43078
- return target;
43079
- }
43080
-
43081
- const VERSION = "3.6.0";
43082
-
43083
- const _excluded = ["authStrategy"];
43084
43181
  class Octokit {
43085
43182
  constructor(options = {}) {
43086
43183
  const hook = new beforeAfterHook.Collection();
@@ -43140,10 +43237,9 @@ class Octokit {
43140
43237
  }
43141
43238
  } else {
43142
43239
  const {
43143
- authStrategy
43144
- } = options,
43145
- otherOptions = _objectWithoutProperties(options, _excluded);
43146
-
43240
+ authStrategy,
43241
+ ...otherOptions
43242
+ } = options;
43147
43243
  const auth = authStrategy(Object.assign({
43148
43244
  request: this.request,
43149
43245
  log: this.log,
@@ -43540,8 +43636,6 @@ function parse(options) {
43540
43636
  } else {
43541
43637
  if (Object.keys(remainingParameters).length) {
43542
43638
  body = remainingParameters;
43543
- } else {
43544
- headers["content-length"] = 0;
43545
43639
  }
43546
43640
  }
43547
43641
  } // default content-type for JSON if body is set
@@ -43584,7 +43678,7 @@ function withDefaults(oldDefaults, newDefaults) {
43584
43678
  });
43585
43679
  }
43586
43680
 
43587
- const VERSION = "6.0.12";
43681
+ const VERSION = "7.0.3";
43588
43682
 
43589
43683
  const userAgent = `octokit-endpoint.js/${VERSION} ${universalUserAgent.getUserAgent()}`; // DEFAULTS has all properties set that EndpointOptions has, except url.
43590
43684
  // So we use RequestParameters and add method as additional required property.
@@ -43621,30 +43715,27 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
43621
43715
  var request = __nccwpck_require__(6234);
43622
43716
  var universalUserAgent = __nccwpck_require__(5030);
43623
43717
 
43624
- const VERSION = "4.8.0";
43718
+ const VERSION = "5.0.4";
43625
43719
 
43626
43720
  function _buildMessageForResponseErrors(data) {
43627
43721
  return `Request failed due to following response errors:\n` + data.errors.map(e => ` - ${e.message}`).join("\n");
43628
43722
  }
43629
-
43630
43723
  class GraphqlResponseError extends Error {
43631
43724
  constructor(request, headers, response) {
43632
43725
  super(_buildMessageForResponseErrors(response));
43633
43726
  this.request = request;
43634
43727
  this.headers = headers;
43635
43728
  this.response = response;
43636
- this.name = "GraphqlResponseError"; // Expose the errors and response data in their shorthand properties.
43637
-
43729
+ this.name = "GraphqlResponseError";
43730
+ // Expose the errors and response data in their shorthand properties.
43638
43731
  this.errors = response.errors;
43639
- this.data = response.data; // Maintains proper stack trace (only available on V8)
43640
-
43732
+ this.data = response.data;
43733
+ // Maintains proper stack trace (only available on V8)
43641
43734
  /* istanbul ignore next */
43642
-
43643
43735
  if (Error.captureStackTrace) {
43644
43736
  Error.captureStackTrace(this, this.constructor);
43645
43737
  }
43646
43738
  }
43647
-
43648
43739
  }
43649
43740
 
43650
43741
  const NON_VARIABLE_OPTIONS = ["method", "baseUrl", "url", "headers", "request", "query", "mediaType"];
@@ -43655,13 +43746,11 @@ function graphql(request, query, options) {
43655
43746
  if (typeof query === "string" && "query" in options) {
43656
43747
  return Promise.reject(new Error(`[@octokit/graphql] "query" cannot be used as variable name`));
43657
43748
  }
43658
-
43659
43749
  for (const key in options) {
43660
43750
  if (!FORBIDDEN_VARIABLE_OPTIONS.includes(key)) continue;
43661
43751
  return Promise.reject(new Error(`[@octokit/graphql] "${key}" cannot be used as variable name`));
43662
43752
  }
43663
43753
  }
43664
-
43665
43754
  const parsedOptions = typeof query === "string" ? Object.assign({
43666
43755
  query
43667
43756
  }, options) : query;
@@ -43670,47 +43759,38 @@ function graphql(request, query, options) {
43670
43759
  result[key] = parsedOptions[key];
43671
43760
  return result;
43672
43761
  }
43673
-
43674
43762
  if (!result.variables) {
43675
43763
  result.variables = {};
43676
43764
  }
43677
-
43678
43765
  result.variables[key] = parsedOptions[key];
43679
43766
  return result;
43680
- }, {}); // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix
43767
+ }, {});
43768
+ // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix
43681
43769
  // https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451
43682
-
43683
43770
  const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl;
43684
-
43685
43771
  if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) {
43686
43772
  requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql");
43687
43773
  }
43688
-
43689
43774
  return request(requestOptions).then(response => {
43690
43775
  if (response.data.errors) {
43691
43776
  const headers = {};
43692
-
43693
43777
  for (const key of Object.keys(response.headers)) {
43694
43778
  headers[key] = response.headers[key];
43695
43779
  }
43696
-
43697
43780
  throw new GraphqlResponseError(requestOptions, headers, response.data);
43698
43781
  }
43699
-
43700
43782
  return response.data.data;
43701
43783
  });
43702
43784
  }
43703
43785
 
43704
- function withDefaults(request$1, newDefaults) {
43705
- const newRequest = request$1.defaults(newDefaults);
43706
-
43786
+ function withDefaults(request, newDefaults) {
43787
+ const newRequest = request.defaults(newDefaults);
43707
43788
  const newApi = (query, options) => {
43708
43789
  return graphql(newRequest, query, options);
43709
43790
  };
43710
-
43711
43791
  return Object.assign(newApi, {
43712
43792
  defaults: withDefaults.bind(null, newRequest),
43713
- endpoint: request.request.endpoint
43793
+ endpoint: newRequest.endpoint
43714
43794
  });
43715
43795
  }
43716
43796
 
@@ -43834,7 +43914,7 @@ var isPlainObject = __nccwpck_require__(3287);
43834
43914
  var nodeFetch = _interopDefault(__nccwpck_require__(467));
43835
43915
  var requestError = __nccwpck_require__(537);
43836
43916
 
43837
- const VERSION = "5.6.3";
43917
+ const VERSION = "6.2.2";
43838
43918
 
43839
43919
  function getBufferResponse(response) {
43840
43920
  return response.arrayBuffer();
@@ -43850,7 +43930,9 @@ function fetchWrapper(requestOptions) {
43850
43930
  let headers = {};
43851
43931
  let status;
43852
43932
  let url;
43853
- const fetch = requestOptions.request && requestOptions.request.fetch || nodeFetch;
43933
+ const fetch = requestOptions.request && requestOptions.request.fetch || globalThis.fetch ||
43934
+ /* istanbul ignore next */
43935
+ nodeFetch;
43854
43936
  return fetch(requestOptions.url, Object.assign({
43855
43937
  method: requestOptions.method,
43856
43938
  body: requestOptions.body,
@@ -43928,7 +44010,7 @@ function fetchWrapper(requestOptions) {
43928
44010
  data
43929
44011
  };
43930
44012
  }).catch(error => {
43931
- if (error instanceof requestError.RequestError) throw error;
44013
+ if (error instanceof requestError.RequestError) throw error;else if (error.name === "AbortError") throw error;
43932
44014
  throw new requestError.RequestError(error.message, 500, {
43933
44015
  request: requestOptions
43934
44016
  });
@@ -52872,11 +52954,12 @@ function asPromise(normalizedOptions) {
52872
52954
  request._beforeError(new types_1.RequestError(error.message, error, request));
52873
52955
  return;
52874
52956
  }
52957
+ globalResponse = response;
52875
52958
  if (!is_response_ok_1.isResponseOk(response)) {
52876
52959
  request._beforeError(new types_1.HTTPError(response));
52877
52960
  return;
52878
52961
  }
52879
- globalResponse = response;
52962
+ request.destroy();
52880
52963
  resolve(request.options.resolveBodyOnly ? response.body : response);
52881
52964
  });
52882
52965
  const onError = (error) => {
@@ -54014,6 +54097,14 @@ class Request extends stream_1.Duplex {
54014
54097
  const redirectUrl = new url_1.URL(redirectBuffer, url);
54015
54098
  const redirectString = redirectUrl.toString();
54016
54099
  decodeURI(redirectString);
54100
+ // eslint-disable-next-line no-inner-declarations
54101
+ function isUnixSocketURL(url) {
54102
+ return url.protocol === 'unix:' || url.hostname === 'unix';
54103
+ }
54104
+ if (!isUnixSocketURL(url) && isUnixSocketURL(redirectUrl)) {
54105
+ this._beforeError(new RequestError('Cannot redirect to UNIX socket', {}, this));
54106
+ return;
54107
+ }
54017
54108
  // Redirecting to a different site, clear sensitive data.
54018
54109
  if (redirectUrl.hostname !== url.hostname || redirectUrl.port !== url.port) {
54019
54110
  if ('host' in options.headers) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cypress/github-action",
3
- "version": "5.0.3",
4
- "description": "GitHub Action for running Cypress end-to-end tests",
3
+ "version": "5.0.7",
4
+ "description": "GitHub Action for running Cypress end-to-end and component tests",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
7
7
  "files": [
@@ -31,11 +31,11 @@
31
31
  },
32
32
  "homepage": "https://github.com/cypress-io/github-action#readme",
33
33
  "dependencies": {
34
- "@actions/cache": "3.0.6",
34
+ "@actions/cache": "3.1.2",
35
35
  "@actions/core": "1.10.0",
36
36
  "@actions/exec": "1.1.1",
37
37
  "@actions/io": "1.1.2",
38
- "@octokit/core": "3.6.0",
38
+ "@octokit/core": "4.2.0",
39
39
  "argument-vector": "1.0.2",
40
40
  "debug": "4.3.4",
41
41
  "execa": "6.1.0",
@@ -45,11 +45,11 @@
45
45
  "quote": "0.4.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@types/node": "18.11.17",
49
- "@vercel/ncc": "0.34.0",
48
+ "@types/node": "18.11.18",
49
+ "@vercel/ncc": "0.36.1",
50
50
  "husky": "7.0.4",
51
51
  "markdown-link-check": "3.10.3",
52
- "prettier": "2.6.2",
52
+ "prettier": "2.8.3",
53
53
  "stop-build": "1.1.0"
54
54
  },
55
55
  "publishConfig": {