Compare commits

..

2 Commits

Author SHA1 Message Date
Deepak Dahiya 5b9b79438b
Update tips-and-workarounds.md 2023-02-14 04:38:03 +05:30
Deepak Dahiya 01f380d654
Updated branch in Force deletion of caches
Fixes this issue https://github.com/actions/cache/issues/1107
2023-02-14 04:32:39 +05:30
55 changed files with 121334 additions and 115922 deletions

View File

@ -15,5 +15,3 @@ jobs:
call-check-dist:
name: Check dist/
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
with:
node-version: "20.x"

View File

@ -14,3 +14,9 @@ jobs:
- name: add_assignees
run: |
curl -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN}}" https://api.github.com/repos/${{github.repository}}/issues/${{ github.event.issue.number}}/assignees -d '{"assignees":["${{steps.oncall.outputs.CURRENT}}"]}'
- uses: actions/add-to-project@v0.4.0
name: Add to Project Board
with:
project-url: https://github.com/orgs/actions/projects/12
github-token: ${{ secrets.CACHE_BOARD_TOKEN }}

View File

@ -18,3 +18,9 @@ jobs:
- name: Add Assignee
run: |
curl -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN}}" https://api.github.com/repos/${{github.repository}}/issues/${{ github.event.pull_request.number}}/assignees -d '{"assignees":["${{steps.oncall.outputs.CURRENT}}"]}'
- uses: actions/add-to-project@v0.4.0
name: Add to Project Board
with:
project-url: https://github.com/orgs/actions/projects/12
github-token: ${{ secrets.CACHE_BOARD_TOKEN }}

View File

@ -1,28 +0,0 @@
name: Release new action version
on:
release:
types: [released]
workflow_dispatch:
inputs:
TAG_NAME:
description: 'Tag name that the major tag will point to'
required: true
env:
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
permissions:
contents: write
jobs:
update_tag:
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
environment:
name: releaseNewActionVersion
runs-on: ubuntu-latest
steps:
- name: Update the ${{ env.TAG_NAME }} tag
id: update-major-tag
uses: actions/publish-action@v0.3.0
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}

View File

@ -21,10 +21,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js 20.x
- name: Setup Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 20.x
node-version: 16.x
cache: npm
- run: npm ci
- name: Prettier Format Check

View File

@ -1,20 +1,20 @@
---
name: "@actions/cache"
version: 3.2.4
version: 3.1.3
type: npm
summary: Actions cache lib
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
summary:
homepage:
license: mit
licenses:
- sources: LICENSE.md
text: |-
The MIT License (MIT)
- sources: LICENSE.md
text: |-
The MIT License (MIT)
Copyright 2019 GitHub
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@ -1,6 +1,6 @@
---
name: "@actions/http-client"
version: 2.1.1
version: 2.0.1
type: npm
summary: Actions Http Client
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client

View File

@ -0,0 +1,32 @@
---
name: "@azure/core-asynciterator-polyfill"
version: 1.0.2
type: npm
summary:
homepage:
license: mit
licenses:
- sources: LICENSE
text: |2
MIT License
Copyright (c) Microsoft Corporation. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
notices: []

View File

@ -1,6 +1,6 @@
---
name: "@azure/core-http"
version: 3.0.4
version: 2.2.4
type: npm
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
libraries generated using AutoRest

View File

@ -1,10 +1,9 @@
---
name: "@azure/core-lro"
version: 2.5.1
version: 2.2.4
type: npm
summary: Isomorphic client library for supporting long-running operations in node.js
and browser.
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-lro/README.md
summary:
homepage:
license: mit
licenses:
- sources: LICENSE

View File

@ -1,6 +1,6 @@
---
name: "@azure/core-paging"
version: 1.5.0
version: 1.2.1
type: npm
summary: Core types for paging async iterable iterators
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-paging/README.md

View File

@ -1,6 +1,6 @@
---
name: "@azure/logger"
version: 1.0.4
version: 1.0.3
type: npm
summary: Microsoft Azure SDK for JavaScript - Logger
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger/README.md

View File

@ -1,10 +1,9 @@
---
name: "@azure/ms-rest-js"
version: 2.7.0
version: 2.6.1
type: npm
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
libraries generated using AutoRest
homepage: https://github.com/Azure/ms-rest-js
summary:
homepage:
license: mit
licenses:
- sources: LICENSE

View File

@ -1,9 +1,9 @@
---
name: "@azure/storage-blob"
version: 12.13.0
version: 12.9.0
type: npm
summary: Microsoft Azure Storage SDK for JavaScript - Blob
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/
summary:
homepage:
license: mit
licenses:
- sources: LICENSE

View File

@ -1,9 +1,9 @@
---
name: "@opentelemetry/api"
version: 1.4.0
version: 1.0.4
type: npm
summary: Public API for OpenTelemetry
homepage: https://github.com/open-telemetry/opentelemetry-js/tree/main/api
homepage: https://github.com/open-telemetry/opentelemetry-js-api#readme
license: apache-2.0
licenses:
- sources: LICENSE
@ -216,8 +216,10 @@ licenses:
[opentelemetry-js]: https://github.com/open-telemetry/opentelemetry-js
[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions
[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/api/LICENSE
[license-url]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/LICENSE
[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat
[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/tracing.md
[docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/sdk-registration.md
[npm-url]: https://www.npmjs.com/package/@opentelemetry/api
[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi.svg
[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/tracing.md
[docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/sdk-registration.md
notices: []

View File

@ -1,9 +1,9 @@
---
name: "@types/node-fetch"
version: 2.6.2
version: 2.6.1
type: npm
summary: TypeScript definitions for node-fetch
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node-fetch
summary:
homepage:
license: mit
licenses:
- sources: LICENSE

View File

@ -1,16 +1,16 @@
---
name: "@azure/core-util"
version: 1.2.0
name: ip-regex
version: 2.1.0
type: npm
summary: Core library for shared utility methods
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-util/
summary: Regular expression for matching IP addresses (IPv4 & IPv6)
homepage: https://github.com/sindresorhus/ip-regex#readme
license: mit
licenses:
- sources: LICENSE
- sources: license
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -19,14 +19,16 @@ licenses:
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
- sources: readme.md
text: MIT © [Sindre Sorhus](https://sindresorhus.com)
notices: []

43
.licenses/npm/psl.dep.yml generated Normal file
View File

@ -0,0 +1,43 @@
---
name: psl
version: 1.8.0
type: npm
summary: Domain name parser based on the Public Suffix List
homepage: https://github.com/lupomontero/psl#readme
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2017 Lupo Montero lupomontero@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- sources: README.md
text: |-
The MIT License (MIT)
Copyright (c) 2017 Lupo Montero <lupomontero@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
notices: []

34
.licenses/npm/punycode.dep.yml generated Normal file
View File

@ -0,0 +1,34 @@
---
name: punycode
version: 2.1.1
type: npm
summary: A robust Punycode converter that fully complies to RFC 3492 and RFC 5891,
and works on nearly all JavaScript platforms.
homepage: https://mths.be/punycode
license: mit
licenses:
- sources: LICENSE-MIT.txt
text: |
Copyright Mathias Bynens <https://mathiasbynens.be/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- sources: README.md
text: Punycode.js is available under the [MIT](https://mths.be/mit) license.
notices: []

View File

@ -1,9 +1,9 @@
---
name: semver
version: 6.3.1
version: 6.3.0
type: npm
summary: The semantic version parser used by npm.
homepage:
homepage: https://github.com/npm/node-semver#readme
license: isc
licenses:
- sources: LICENSE

23
.licenses/npm/tough-cookie-3.0.1.dep.yml generated Normal file
View File

@ -0,0 +1,23 @@
---
name: tough-cookie
version: 3.0.1
type: npm
summary: RFC6265 Cookies and Cookie Jar for node.js
homepage: https://github.com/salesforce/tough-cookie
license: bsd-3-clause
licenses:
- sources: LICENSE
text: |
Copyright (c) 2015, Salesforce.com, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
notices: []

23
.licenses/npm/tough-cookie-4.0.0.dep.yml generated Normal file
View File

@ -0,0 +1,23 @@
---
name: tough-cookie
version: 4.0.0
type: npm
summary: RFC6265 Cookies and Cookie Jar for node.js
homepage: https://github.com/salesforce/tough-cookie
license: bsd-3-clause
licenses:
- sources: LICENSE
text: |
Copyright (c) 2015, Salesforce.com, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
notices: []

View File

@ -1,23 +0,0 @@
---
name: tslib
version: 2.5.0
type: npm
summary: Runtime library for TypeScript helper functions
homepage: https://www.typescriptlang.org/
license: 0bsd
licenses:
- sources: LICENSE.txt
text: |-
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
notices: []

33
.licenses/npm/universalify.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: universalify
version: 0.1.2
type: npm
summary: Make a callback- or promise-based function support both promises and callbacks.
homepage: https://github.com/RyanZim/universalify#readme
license: mit
licenses:
- sources: LICENSE
text: |
(The MIT License)
Copyright (c) 2017, Ryan Zimmerman <opensrc@ryanzim.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the 'Software'), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- sources: README.md
text: MIT
notices: []

View File

@ -1,6 +1,6 @@
---
name: xml2js
version: 0.5.0
version: 0.4.23
type: npm
summary: Simple XML to JavaScript object converter.
homepage: https://github.com/Leonidas-from-XIV/node-xml2js

View File

@ -2,9 +2,11 @@
This action allows caching dependencies and build outputs to improve workflow execution time.
>Two other actions are available in addition to the primary `cache` action:
>* [Restore action](./restore/README.md)
>* [Save action](./save/README.md)
Two other actions are available in addition to the primary `cache` action:
* [Restore action](./restore/README.md)
* [Save action](./save/README.md)
[![Tests](https://github.com/actions/cache/actions/workflows/workflow.yml/badge.svg)](https://github.com/actions/cache/actions/workflows/workflow.yml)
@ -14,11 +16,6 @@ See ["Caching dependencies to speed up workflows"](https://docs.github.com/en/ac
## What's New
### v4
* Updated to node 20
* Added a `save-always` flag to save the cache even if a prior step fails
### v3
* Added support for caching in GHES 3.5+.
@ -30,13 +27,10 @@ See ["Caching dependencies to speed up workflows"](https://docs.github.com/en/ac
* Fixed cache not working with github workspace directory or current directory.
* Fixed the download stuck problem by introducing a timeout of 1 hour for cache downloads.
* Fix zstd not working for windows on gnu tar in issues.
* Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable `SEGMENT_DOWNLOAD_TIMEOUT_MINS`. Default is 10 minutes.
* Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable `SEGMENT_DOWNLOAD_TIMEOUT_MINS`. Default is 60 minutes.
* New actions are available for granular control over caches - [restore](restore/action.yml) and [save](save/action.yml).
* Support cross-os caching as an opt-in feature. See [Cross OS caching](./tips-and-workarounds.md#cross-os-cache) for more info.
* Added option to fail job on cache miss. See [Exit workflow on cache miss](./restore/README.md#exit-workflow-on-cache-miss) for more info.
* Fix zstd not being used after zstd version upgrade to 1.5.4 on hosted runners
* Added option to lookup cache without downloading it.
* Reduced segment size to 128MB and segment timeout to 10 minutes to fail fast in case the cache download is stuck.
See the [v2 README.md](https://github.com/actions/cache/blob/v2/README.md) for older updates.
@ -54,14 +48,13 @@ If you are using a `self-hosted` Windows runner, `GNU tar` and `zstd` are requir
* `key` - An explicit key for a cache entry. See [creating a cache key](#creating-a-cache-key).
* `path` - A list of files, directories, and wildcard patterns to cache and restore. See [`@actions/glob`](https://github.com/actions/toolkit/tree/main/packages/glob) for supported patterns.
* `restore-keys` - An ordered multiline string listing the prefix-matched keys, that are used for restoring stale cache if no cache hit occurred for key.
* `restore-keys` - An ordered list of prefix-matched keys to use for restoring stale cache if no cache hit occurred for key.
* `enableCrossOsArchive` - An optional boolean when enabled, allows Windows runners to save or restore caches that can be restored or saved respectively on other platforms. Default: `false`
* `fail-on-cache-miss` - Fail the workflow if cache entry is not found. Default: `false`
* `lookup-only` - If true, only checks if cache entry exists and skips download. Does not change save cache behavior. Default: `false`
#### Environment Variables
* `SEGMENT_DOWNLOAD_TIMEOUT_MINS` - Segment download timeout (in minutes, default `10`) to abort download of the segment if not completed in the defined number of minutes. [Read more](https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout)
* `SEGMENT_DOWNLOAD_TIMEOUT_MINS` - Segment download timeout (in minutes, default `60`) to abort download of the segment if not completed in the defined number of minutes. [Read more](https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout)
### Outputs
@ -91,11 +84,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Cache Primes
id: cache-primes
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: prime-numbers
key: ${{ runner.os }}-primes
@ -122,11 +115,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Restore cached Primes
id: cache-primes-restore
uses: actions/cache/restore@v4
uses: actions/cache/restore@v3
with:
path: |
path/to/dependencies
@ -137,7 +130,7 @@ jobs:
.
- name: Save Primes
id: cache-primes-save
uses: actions/cache/save@v4
uses: actions/cache/save@v3
with:
path: |
path/to/dependencies
@ -191,7 +184,7 @@ A cache key can include any of the contexts, functions, literals, and operators
For example, using the [`hashFiles`](https://docs.github.com/en/actions/learn-github-actions/expressions#hashfiles) function allows you to create a new cache when dependencies change.
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
path/to/dependencies
@ -209,7 +202,7 @@ Additionally, you can use arbitrary command output in a cache key, such as a dat
echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
shell: bash
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: path/to/dependencies
key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/lockfiles') }}
@ -229,9 +222,9 @@ Example:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/cache@v4
- uses: actions/cache@v3
id: cache
with:
path: path/to/dependencies
@ -259,11 +252,11 @@ jobs:
build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Cache Primes
id: cache-primes
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: prime-numbers
key: primes
@ -274,7 +267,7 @@ jobs:
- name: Cache Numbers
id: cache-numbers
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: numbers
key: primes
@ -286,11 +279,11 @@ jobs:
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Cache Primes
id: cache-primes
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: prime-numbers
key: primes

View File

@ -1,130 +1,75 @@
# Releases
### 4.0.2
### 3.0.0
- Updated minimum runner version support from node 12 -> node 16
- Fixed restore `fail-on-cache-miss` not working.
### 3.0.1
- Added support for caching from GHES 3.5.
- Fixed download issue for files > 2GB during restore.
### 4.0.1
### 3.0.2
- Added support for dynamic cache size cap on GHES.
- Updated `isGhes` check
### 3.0.3
- Fixed avoiding empty cache save when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624))
### 4.0.0
### 3.0.4
- Fixed tar creation error while trying to create tar with path as `~/` home folder on `ubuntu-latest`. ([issue](https://github.com/actions/cache/issues/689))
- Updated minimum runner version support from node 12 -> node 20
### 3.0.5
- Removed error handling by consuming actions/cache 3.0 toolkit, Now cache server error handling will be done by toolkit. ([PR](https://github.com/actions/cache/pull/834))
### 3.3.3
### 3.0.6
- Fixed [#809](https://github.com/actions/cache/issues/809) - zstd -d: no such file or directory error
- Fixed [#833](https://github.com/actions/cache/issues/833) - cache doesn't work with github workspace directory
- Updates @actions/cache to v3.2.3 to fix accidental mutated path arguments to `getCacheVersion` [actions/toolkit#1378](https://github.com/actions/toolkit/pull/1378)
- Additional audit fixes of npm package(s)
### 3.0.7
- Fixed [#810](https://github.com/actions/cache/issues/810) - download stuck issue. A new timeout is introduced in the download process to abort the download if it gets stuck and doesn't finish within an hour.
### 3.3.2
### 3.0.8
- Fix zstd not working for windows on gnu tar in issues [#888](https://github.com/actions/cache/issues/888) and [#891](https://github.com/actions/cache/issues/891).
- Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable `SEGMENT_DOWNLOAD_TIMEOUT_MINS`. Default is 60 minutes.
- Fixes bug with Azure SDK causing blob downloads to get stuck.
### 3.0.9
- Enhanced the warning message for cache unavailablity in case of GHES.
### 3.3.1
### 3.0.10
- Fix a bug with sorting inputs.
- Update definition for restore-keys in README.md
- Reduced segment size to 128MB and segment timeout to 10 minutes to fail fast in case the cache download is stuck.
### 3.0.11
- Update toolkit version to 3.0.5 to include `@actions/core@^1.10.0`
- Update `@actions/cache` to use updated `saveState` and `setOutput` functions from `@actions/core@^1.10.0`
### 3.3.0
### 3.1.0-beta.1
- Update `@actions/cache` on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. ([issue](https://github.com/actions/cache/issues/984))
- Added option to lookup cache without downloading it.
### 3.1.0-beta.2
- Added support for fallback to gzip to restore old caches on windows.
### 3.2.6
### 3.1.0-beta.3
- Bug fixes for bsdtar fallback if gnutar not available and gzip fallback if cache saved using old cache action on windows.
- Fix zstd not being used after zstd version upgrade to 1.5.4 on hosted runners.
### 3.2.0-beta.1
- Added two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache.
### 3.2.5
- Added fix to prevent from setting MYSYS environment variable globally.
### 3.2.4
- Added option to fail job on cache miss.
### 3.2.3
- Support cross os caching on Windows as an opt-in feature.
- Fix issue with symlink restoration on Windows for cross-os caches.
### 3.2.2
- Reverted the changes made in 3.2.1 to use gnu tar and zstd by default on windows.
### 3.2.0
- Released the two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache
### 3.2.1
- Update `@actions/cache` on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. ([issue](https://github.com/actions/cache/issues/984))
- Added support for fallback to gzip to restore old caches on windows.
- Added logs for cache version in case of a cache miss.
### 3.2.0
### 3.2.2
- Reverted the changes made in 3.2.1 to use gnu tar and zstd by default on windows.
- Released the two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache
### 3.2.3
- Support cross os caching on Windows as an opt-in feature.
- Fix issue with symlink restoration on Windows for cross-os caches.
### 3.2.0-beta.1
### 3.2.4
- Added option to fail job on cache miss.
- Added two new actions - [restore](restore/action.yml) and [save](save/action.yml) for granular control on cache.
### 3.1.0-beta.3
- Bug fixes for bsdtar fallback if gnutar not available and gzip fallback if cache saved using old cache action on windows.
### 3.1.0-beta.2
- Added support for fallback to gzip to restore old caches on windows.
### 3.1.0-beta.1
- Update `@actions/cache` on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. ([issue](https://github.com/actions/cache/issues/984))
### 3.0.11
- Update toolkit version to 3.0.5 to include `@actions/core@^1.10.0`
- Update `@actions/cache` to use updated `saveState` and `setOutput` functions from `@actions/core@^1.10.0`
### 3.0.10
- Fix a bug with sorting inputs.
- Update definition for restore-keys in README.md
### 3.0.9
- Enhanced the warning message for cache unavailablity in case of GHES.
### 3.0.8
- Fix zstd not working for windows on gnu tar in issues [#888](https://github.com/actions/cache/issues/888) and [#891](https://github.com/actions/cache/issues/891).
- Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable `SEGMENT_DOWNLOAD_TIMEOUT_MINS`. Default is 60 minutes.
### 3.0.7
- Fixed [#810](https://github.com/actions/cache/issues/810) - download stuck issue. A new timeout is introduced in the download process to abort the download if it gets stuck and doesn't finish within an hour.
### 3.0.6
- Fixed [#809](https://github.com/actions/cache/issues/809) - zstd -d: no such file or directory error
- Fixed [#833](https://github.com/actions/cache/issues/833) - cache doesn't work with github workspace directory
### 3.0.5
- Removed error handling by consuming actions/cache 3.0 toolkit, Now cache server error handling will be done by toolkit. ([PR](https://github.com/actions/cache/pull/834))
### 3.0.4
- Fixed tar creation error while trying to create tar with path as `~/` home folder on `ubuntu-latest`. ([issue](https://github.com/actions/cache/issues/689))
### 3.0.3
- Fixed avoiding empty cache save when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624))
### 3.0.2
- Added support for dynamic cache size cap on GHES.
### 3.0.1
- Added support for caching from GHES 3.5.
- Fixed download issue for files > 2GB during restore.
### 3.0.0
- Updated minimum runner version support from node 12 -> node 16
### 3.2.5
- Added fix to prevent from setting MYSYS environment variable globally.

View File

@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { Events, RefKey } from "../src/constants";
import { restoreRun } from "../src/restoreImpl";
import run from "../src/restore";
import * as actionUtils from "../src/utils/actionUtils";
import * as testUtils from "../src/utils/testUtils";
@ -71,18 +71,10 @@ test("restore with no cache found", async () => {
return Promise.resolve(undefined);
});
await restoreRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: false
},
false
);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [], {}, false);
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(stateMock).toHaveBeenCalledTimes(1);
@ -114,16 +106,14 @@ test("restore with restore keys and no cache found", async () => {
return Promise.resolve(undefined);
});
await restoreRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[restoreKey],
{
lookupOnly: false
},
{},
false
);
@ -156,18 +146,10 @@ test("restore with cache found for key", async () => {
return Promise.resolve(key);
});
await restoreRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: false
},
false
);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [], {}, false);
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(stateMock).toHaveBeenCalledWith("CACHE_RESULT", key);
@ -201,16 +183,14 @@ test("restore with cache found for restore key", async () => {
return Promise.resolve(restoreKey);
});
await restoreRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[restoreKey],
{
lookupOnly: false
},
{},
false
);
@ -246,21 +226,19 @@ test("Fail restore when fail on cache miss is enabled and primary + restore keys
return Promise.resolve(undefined);
});
await restoreRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[restoreKey],
{
lookupOnly: false
},
{},
false
);
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(0);
expect(failedMock).toHaveBeenCalledWith(
`Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${key}`
@ -289,16 +267,14 @@ test("restore when fail on cache miss is enabled and primary key doesn't match r
return Promise.resolve(restoreKey);
});
await restoreRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[restoreKey],
{
lookupOnly: false
},
{},
false
);
@ -335,16 +311,14 @@ test("restore with fail on cache miss disabled and no cache found", async () =>
return Promise.resolve(undefined);
});
await restoreRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[restoreKey],
{
lookupOnly: false
},
{},
false
);

View File

@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { Events, Inputs, RefKey } from "../src/constants";
import { restoreImpl } from "../src/restoreImpl";
import run from "../src/restoreImpl";
import { StateProvider } from "../src/stateProvider";
import * as actionUtils from "../src/utils/actionUtils";
import * as testUtils from "../src/utils/testUtils";
@ -60,7 +60,7 @@ test("restore with invalid event outputs warning", async () => {
const invalidEvent = "commit_comment";
process.env[Events.Key] = invalidEvent;
delete process.env[RefKey];
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(logWarningMock).toHaveBeenCalledWith(
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
);
@ -76,7 +76,7 @@ test("restore without AC available should no-op", async () => {
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
@ -92,7 +92,7 @@ test("restore on GHES without AC available should no-op", async () => {
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
@ -119,18 +119,10 @@ test("restore on GHES with AC available ", async () => {
return Promise.resolve(key);
});
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: false
},
false
);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [], {}, false);
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
@ -143,7 +135,7 @@ test("restore on GHES with AC available ", async () => {
test("restore with no path should fail", async () => {
const failedMock = jest.spyOn(core, "setFailed");
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
// this input isn't necessary for restore b/c tarball contains entries relative to workspace
expect(failedMock).not.toHaveBeenCalledWith(
@ -155,7 +147,7 @@ test("restore with no key", async () => {
testUtils.setInput(Inputs.Path, "node_modules");
const failedMock = jest.spyOn(core, "setFailed");
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
expect(failedMock).toHaveBeenCalledWith(
"Input required and not supplied: key"
@ -174,15 +166,13 @@ test("restore with too many keys should fail", async () => {
});
const failedMock = jest.spyOn(core, "setFailed");
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
restoreKeys,
{
lookupOnly: false
},
{},
false
);
expect(failedMock).toHaveBeenCalledWith(
@ -200,17 +190,9 @@ test("restore with large key should fail", async () => {
});
const failedMock = jest.spyOn(core, "setFailed");
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: false
},
false
);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [], {}, false);
expect(failedMock).toHaveBeenCalledWith(
`Key Validation Error: ${key} cannot be larger than 512 characters.`
);
@ -226,17 +208,9 @@ test("restore with invalid key should fail", async () => {
});
const failedMock = jest.spyOn(core, "setFailed");
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: false
},
false
);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [], {}, false);
expect(failedMock).toHaveBeenCalledWith(
`Key Validation Error: ${key} cannot contain commas.`
);
@ -260,18 +234,10 @@ test("restore with no cache found", async () => {
return Promise.resolve(undefined);
});
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: false
},
false
);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [], {}, false);
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(failedMock).toHaveBeenCalledTimes(0);
@ -301,16 +267,14 @@ test("restore with restore keys and no cache found", async () => {
return Promise.resolve(undefined);
});
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[restoreKey],
{
lookupOnly: false
},
{},
false
);
@ -341,18 +305,10 @@ test("restore with cache found for key", async () => {
return Promise.resolve(key);
});
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: false
},
false
);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [], {}, false);
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
@ -383,16 +339,14 @@ test("restore with cache found for restore key", async () => {
return Promise.resolve(restoreKey);
});
await restoreImpl(new StateProvider());
await run(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[restoreKey],
{
lookupOnly: false
},
{},
false
);
@ -404,64 +358,3 @@ test("restore with cache found for restore key", async () => {
);
expect(failedMock).toHaveBeenCalledTimes(0);
});
test("restore with lookup-only set", async () => {
const path = "node_modules";
const key = "node-test";
testUtils.setInputs({
path: path,
key,
lookupOnly: true
});
const infoMock = jest.spyOn(core, "info");
const failedMock = jest.spyOn(core, "setFailed");
const stateMock = jest.spyOn(core, "saveState");
const setCacheHitOutputMock = jest.spyOn(core, "setOutput");
const restoreCacheMock = jest
.spyOn(cache, "restoreCache")
.mockImplementationOnce(() => {
return Promise.resolve(key);
});
await restoreImpl(new StateProvider());
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: true
},
false
);
expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
expect(stateMock).toHaveBeenCalledWith("CACHE_RESULT", key);
expect(stateMock).toHaveBeenCalledTimes(2);
expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true");
expect(infoMock).toHaveBeenCalledWith(
`Cache found and can be restored from key: ${key}`
);
expect(failedMock).toHaveBeenCalledTimes(0);
});
test("restore failure with earlyExit should call process exit", async () => {
testUtils.setInput(Inputs.Path, "node_modules");
const failedMock = jest.spyOn(core, "setFailed");
const restoreCacheMock = jest.spyOn(cache, "restoreCache");
const processExitMock = jest.spyOn(process, "exit").mockImplementation();
// call restoreImpl with `earlyExit` set to true
await restoreImpl(new StateProvider(), true);
expect(restoreCacheMock).toHaveBeenCalledTimes(0);
expect(failedMock).toHaveBeenCalledWith(
"Input required and not supplied: key"
);
expect(processExitMock).toHaveBeenCalledWith(1);
});

View File

@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { Events, RefKey } from "../src/constants";
import { restoreOnlyRun } from "../src/restoreImpl";
import run from "../src/restoreOnly";
import * as actionUtils from "../src/utils/actionUtils";
import * as testUtils from "../src/utils/testUtils";
@ -72,22 +72,13 @@ test("restore with no cache found", async () => {
return Promise.resolve(undefined);
});
await restoreOnlyRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: false
},
false
);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [], {}, false);
expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key);
expect(outputMock).toHaveBeenCalledWith("cache-hit", "false");
expect(outputMock).toHaveBeenCalledTimes(2);
expect(outputMock).toHaveBeenCalledTimes(1);
expect(failedMock).toHaveBeenCalledTimes(0);
expect(infoMock).toHaveBeenCalledWith(
@ -115,16 +106,14 @@ test("restore with restore keys and no cache found", async () => {
return Promise.resolve(undefined);
});
await restoreOnlyRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[restoreKey],
{
lookupOnly: false
},
{},
false
);
@ -154,18 +143,10 @@ test("restore with cache found for key", async () => {
return Promise.resolve(key);
});
await restoreOnlyRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[],
{
lookupOnly: false
},
false
);
expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [], {}, false);
expect(outputMock).toHaveBeenCalledWith("cache-primary-key", key);
expect(outputMock).toHaveBeenCalledWith("cache-hit", "true");
@ -197,16 +178,14 @@ test("restore with cache found for restore key", async () => {
return Promise.resolve(restoreKey);
});
await restoreOnlyRun();
await run();
expect(restoreCacheMock).toHaveBeenCalledTimes(1);
expect(restoreCacheMock).toHaveBeenCalledWith(
[path],
key,
[restoreKey],
{
lookupOnly: false
},
{},
false
);

View File

@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { Events, Inputs, RefKey } from "../src/constants";
import { saveRun } from "../src/saveImpl";
import run from "../src/save";
import * as actionUtils from "../src/utils/actionUtils";
import * as testUtils from "../src/utils/testUtils";
@ -100,7 +100,7 @@ test("save with valid inputs uploads a cache", async () => {
return Promise.resolve(cacheId);
});
await saveRun();
await run();
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(saveCacheMock).toHaveBeenCalledWith(

View File

@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { Events, Inputs, RefKey } from "../src/constants";
import { saveImpl } from "../src/saveImpl";
import run from "../src/saveImpl";
import { StateProvider } from "../src/stateProvider";
import * as actionUtils from "../src/utils/actionUtils";
import * as testUtils from "../src/utils/testUtils";
@ -77,7 +77,7 @@ test("save with invalid event outputs warning", async () => {
const invalidEvent = "commit_comment";
process.env[Events.Key] = invalidEvent;
delete process.env[RefKey];
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(logWarningMock).toHaveBeenCalledWith(
`Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.`
);
@ -100,7 +100,7 @@ test("save with no primary key in state outputs warning", async () => {
});
const saveCacheMock = jest.spyOn(cache, "saveCache");
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(0);
expect(logWarningMock).toHaveBeenCalledWith(`Key is not specified.`);
@ -115,7 +115,7 @@ test("save without AC available should no-op", async () => {
const saveCacheMock = jest.spyOn(cache, "saveCache");
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(0);
});
@ -128,7 +128,7 @@ test("save on ghes without AC available should no-op", async () => {
const saveCacheMock = jest.spyOn(cache, "saveCache");
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(0);
});
@ -161,7 +161,7 @@ test("save on GHES with AC available", async () => {
return Promise.resolve(cacheId);
});
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(saveCacheMock).toHaveBeenCalledWith(
@ -194,7 +194,7 @@ test("save with exact match returns early", async () => {
});
const saveCacheMock = jest.spyOn(cache, "saveCache");
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(0);
expect(infoMock).toHaveBeenCalledWith(
@ -221,7 +221,7 @@ test("save with missing input outputs warning", async () => {
});
const saveCacheMock = jest.spyOn(cache, "saveCache");
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(0);
expect(logWarningMock).toHaveBeenCalledWith(
@ -259,7 +259,7 @@ test("save with large cache outputs warning", async () => {
);
});
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(saveCacheMock).toHaveBeenCalledWith(
@ -306,7 +306,7 @@ test("save with reserve cache failure outputs warning", async () => {
throw error;
});
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(saveCacheMock).toHaveBeenCalledWith(
@ -349,7 +349,7 @@ test("save with server error outputs warning", async () => {
throw new Error("HTTP Error Occurred");
});
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(saveCacheMock).toHaveBeenCalledWith(
@ -392,7 +392,7 @@ test("save with valid inputs uploads a cache", async () => {
return Promise.resolve(cacheId);
});
await saveImpl(new StateProvider());
await run(new StateProvider());
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(saveCacheMock).toHaveBeenCalledWith(

View File

@ -2,7 +2,7 @@ import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { Events, Inputs, RefKey } from "../src/constants";
import { saveOnlyRun } from "../src/saveImpl";
import run from "../src/saveOnly";
import * as actionUtils from "../src/utils/actionUtils";
import * as testUtils from "../src/utils/testUtils";
@ -90,7 +90,7 @@ test("save with valid inputs uploads a cache", async () => {
return Promise.resolve(cacheId);
});
await saveOnlyRun();
await run();
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(saveCacheMock).toHaveBeenCalledWith(
@ -122,7 +122,7 @@ test("save failing logs the warning message", async () => {
return Promise.resolve(cacheId);
});
await saveOnlyRun();
await run();
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(saveCacheMock).toHaveBeenCalledWith(

View File

@ -9,7 +9,7 @@ inputs:
description: 'An explicit key for restoring and saving the cache'
required: true
restore-keys:
description: 'An ordered multiline string listing the prefix-matched keys, that are used for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
description: 'An ordered list of keys to use for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
required: false
upload-chunk-size:
description: 'The chunk size used to split up large files during upload, in bytes'
@ -22,22 +22,14 @@ inputs:
description: 'Fail the workflow if cache entry is not found'
default: 'false'
required: false
lookup-only:
description: 'Check if a cache entry exists for the given input(s) (key, restore-keys) without downloading the cache'
default: 'false'
required: false
save-always:
description: 'Run the post step to save the cache even if another step before fails'
default: 'false'
required: false
outputs:
cache-hit:
description: 'A boolean value to indicate an exact match was found for the primary key'
runs:
using: 'node20'
using: 'node16'
main: 'dist/restore/index.js'
post: 'dist/save/index.js'
post-if: "success() || github.event.inputs.save-always"
post-if: success()
branding:
icon: 'archive'
color: 'gray-dark'

View File

@ -12,7 +12,7 @@ This document lists some of the strategies (and example workflows if possible) w
jobs:
build:
runs-on: ubuntu-latest
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
key: ${{ some-metadata }}-cache
```
@ -24,7 +24,7 @@ In your workflows, you can use different strategies to name your key depending o
One of the most common use case is to use hash for lockfile as key. This way, same cache will be restored for a lockfile until there's a change in dependencies listed in lockfile.
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
path/to/dependencies
@ -37,7 +37,7 @@ One of the most common use case is to use hash for lockfile as key. This way, sa
If cache is not found matching the primary key, restore keys can be used to download the closest matching cache that was recently created. This ensures that the build/install step will need to additionally fetch just a handful of newer dependencies, and hence saving build time.
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
path/to/dependencies
@ -54,7 +54,7 @@ The restore keys can be provided as a complete name, or a prefix, read more [her
In case of workflows with matrix running for multiple Operating Systems, the caches can be stored separately for each of them. This can be used in combination with hashfiles in case multiple caches are being generated per OS.
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
path/to/dependencies
@ -73,7 +73,7 @@ Caches scoped to the particular workflow run id or run attempt can be stored and
On similar lines, commit sha can be used to create a very specialized and short lived cache.
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
path/to/dependencies
@ -86,7 +86,7 @@ On similar lines, commit sha can be used to create a very specialized and short
Cache key can be formed by combination of more than one metadata, evaluated info.
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
path/to/dependencies
@ -146,9 +146,9 @@ In case you are using a centralized job to create and save your cache that can b
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/cache/restore@v4
- uses: actions/cache/restore@v3
id: cache
with:
path: path/to/dependencies
@ -171,9 +171,9 @@ You can use the output of this action to exit the workflow on cache miss. This w
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/cache/restore@v4
- uses: actions/cache/restore@v3
id: cache
with:
path: path/to/dependencies
@ -194,7 +194,7 @@ steps:
If you want to avoid re-computing the cache key again in `save` action, the outputs from `restore` action can be used as input to the `save` action.
```yaml
- uses: actions/cache/restore@v4
- uses: actions/cache/restore@v3
id: restore-cache
with:
path: |
@ -204,7 +204,7 @@ If you want to avoid re-computing the cache key again in `save` action, the outp
.
.
.
- uses: actions/cache/save@v4
- uses: actions/cache/save@v3
with:
path: |
path/to/dependencies
@ -219,7 +219,7 @@ On the other hand, the key can also be explicitly re-computed while executing th
Let's say we have a restore step that computes key at runtime
```yaml
uses: actions/cache/restore@v4
uses: actions/cache/restore@v3
id: restore-cache
with:
key: cache-${{ hashFiles('**/lockfiles') }}
@ -228,7 +228,7 @@ with:
Case 1: Where an user would want to reuse the key as it is
```yaml
uses: actions/cache/save@v4
uses: actions/cache/save@v3
with:
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
```
@ -236,7 +236,7 @@ with:
Case 2: Where the user would want to re-evaluate the key
```yaml
uses: actions/cache/save@v4
uses: actions/cache/save@v3
with:
key: npm-cache-${{hashfiles(package-lock.json)}}
```
@ -249,13 +249,13 @@ Similarly, `actions/cache/save` action can be conditionally used based on the ou
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
.
. // restore if need be
.
- name: Build
run: /build.sh
- uses: actions/cache/save@v4
- uses: actions/cache/save@v3
if: always() // or any other condition to invoke the save action
with:
path: path/to/dependencies
@ -270,12 +270,12 @@ In case of multi-module projects, where the built artifact of one project needs
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Build
run: ./build-parent-module.sh
- uses: actions/cache/save@v4
- uses: actions/cache/save@v3
id: cache
with:
path: path/to/dependencies
@ -286,9 +286,9 @@ steps:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/cache/restore@v4
- uses: actions/cache/restore@v3
id: cache
with:
path: path/to/dependencies

File diff suppressed because one or more lines are too long

58639
dist/restore/index.js vendored

File diff suppressed because one or more lines are too long

58640
dist/save-only/index.js vendored

File diff suppressed because one or more lines are too long

58647
dist/save/index.js vendored

File diff suppressed because one or more lines are too long

View File

@ -39,14 +39,13 @@
- [Swift, Objective-C - CocoaPods](#swift-objective-c---cocoapods)
- [Swift - Swift Package Manager](#swift---swift-package-manager)
- [Swift - Mint](#swift---mint)
- [* - Bazel](#---bazel)
## C# - NuGet
Using [NuGet lock files](https://docs.microsoft.com/nuget/consume-packages/package-references-in-project-files#locking-dependencies):
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
@ -55,10 +54,10 @@ Using [NuGet lock files](https://docs.microsoft.com/nuget/consume-packages/packa
```
Depending on the environment, huge packages might be pre-installed in the global cache folder.
With `actions/cache@v4` you can now exclude unwanted packages with [exclude pattern](https://github.com/actions/toolkit/tree/main/packages/glob#exclude-patterns)
With `actions/cache@v3` you can now exclude unwanted packages with [exclude pattern](https://github.com/actions/toolkit/tree/main/packages/glob#exclude-patterns)
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~/.nuget/packages
@ -75,7 +74,7 @@ Or you could move the cache folder like below.
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: ${{ github.workspace }}/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
@ -87,7 +86,7 @@ steps:
```yaml
- name: Cache lein project dependencies
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-clojure-${{ hashFiles('**/project.clj') }}
@ -101,7 +100,7 @@ steps:
### POSIX
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: ~/.dub
key: ${{ runner.os }}-dub-${{ hashFiles('**/dub.selections.json') }}
@ -112,7 +111,7 @@ steps:
### Windows
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: ~\AppData\Local\dub
key: ${{ runner.os }}-dub-${{ hashFiles('**/dub.selections.json') }}
@ -125,7 +124,7 @@ steps:
### Linux
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~/.deno
@ -136,7 +135,7 @@ steps:
### macOS
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~/.deno
@ -147,7 +146,7 @@ steps:
### Windows
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~\.deno
@ -158,7 +157,7 @@ steps:
## Elixir - Mix
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
deps
@ -185,7 +184,7 @@ steps:
### Linux
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~/.cache/go-build
@ -198,7 +197,7 @@ steps:
### macOS
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~/Library/Caches/go-build
@ -211,7 +210,7 @@ steps:
### Windows
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~\AppData\Local\go-build
@ -227,7 +226,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
```yaml
- name: Cache ~/.cabal/packages, ~/.cabal/store and dist-newstyle
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: |
~/.cabal/packages
@ -242,14 +241,14 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
### Linux or macOS
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
name: Cache ~/.stack
with:
path: ~/.stack
key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}
restore-keys: |
${{ runner.os }}-stack-global-
- uses: actions/cache@v4
- uses: actions/cache@v3
name: Cache .stack-work
with:
path: .stack-work
@ -261,7 +260,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
### Windows
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
name: Cache %APPDATA%\stack %LOCALAPPDATA%\Programs\stack
with:
path: |
@ -270,7 +269,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
key: ${{ runner.os }}-stack-global-${{ hashFiles('stack.yaml') }}-${{ hashFiles('package.yaml') }}
restore-keys: |
${{ runner.os }}-stack-global-
- uses: actions/cache@v4
- uses: actions/cache@v3
name: Cache .stack-work
with:
path: .stack-work
@ -284,7 +283,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
> **Note** Ensure no Gradle daemons are running anymore when your workflow completes. Creating the cache package might fail due to locks being held by Gradle. Refer to the [Gradle Daemon documentation](https://docs.gradle.org/current/userguide/gradle_daemon.html) on how to disable or stop the Gradle Daemons.
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -298,7 +297,7 @@ We cache the elements of the Cabal store separately, as the entirety of `~/.caba
```yaml
- name: Cache local Maven repository
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
@ -334,7 +333,7 @@ After [deprecation](https://github.blog/changelog/2022-10-11-github-actions-depr
`Get npm cache directory` step can then be used with `actions/cache` as shown below
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
@ -347,7 +346,7 @@ After [deprecation](https://github.blog/changelog/2022-10-11-github-actions-depr
```yaml
- name: restore lerna
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
@ -361,7 +360,7 @@ The yarn cache directory will depend on your operating system and version of `ya
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
- uses: actions/cache@v3
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@ -379,7 +378,7 @@ The yarn 2 cache directory will depend on your config. See https://yarnpkg.com/c
id: yarn-cache-dir-path
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
- uses: actions/cache@v3
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@ -394,7 +393,7 @@ Esy allows you to export built dependencies and import pre-built dependencies.
```yaml
- name: Restore Cache
id: restore-cache
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: _export
key: ${{ runner.os }}-esy-${{ hashFiles('esy.lock/index.json') }}
@ -423,7 +422,7 @@ Esy allows you to export built dependencies and import pre-built dependencies.
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
@ -444,7 +443,7 @@ Locations:
### Simple example
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
@ -457,7 +456,7 @@ Replace `~/.cache/pip` with the correct `path` if not using Ubuntu.
### Multiple OS's in a workflow
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
if: startsWith(runner.os, 'Linux')
with:
path: ~/.cache/pip
@ -465,7 +464,7 @@ Replace `~/.cache/pip` with the correct `path` if not using Ubuntu.
restore-keys: |
${{ runner.os }}-pip-
- uses: actions/cache@v4
- uses: actions/cache@v3
if: startsWith(runner.os, 'macOS')
with:
path: ~/Library/Caches/pip
@ -473,7 +472,7 @@ Replace `~/.cache/pip` with the correct `path` if not using Ubuntu.
restore-keys: |
${{ runner.os }}-pip-
- uses: actions/cache@v4
- uses: actions/cache@v3
if: startsWith(runner.os, 'Windows')
with:
path: ~\AppData\Local\pip\Cache
@ -499,7 +498,7 @@ jobs:
- os: windows-latest
path: ~\AppData\Local\pip\Cache
steps:
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: ${{ matrix.path }}
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
@ -513,12 +512,11 @@ jobs:
```yaml
- name: Get pip cache dir
id: pip-cache
shell: bash
run: |
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
- name: pip cache
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
@ -536,7 +534,7 @@ jobs:
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: ~/.local/share/virtualenvs
key: ${{ runner.os }}-python-${{ steps.setup-python.outputs.python-version }}-pipenv-${{ hashFiles('Pipfile.lock') }}
@ -563,7 +561,7 @@ For renv, the cache directory will vary by OS. The `RENV_PATHS_ROOT` environment
cat("##[set-output name=r-version;]", R.Version()$version.string, sep = "")
shell: Rscript {0}
- name: Restore Renv package cache
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: ${{ env.RENV_PATHS_ROOT }}
key: ${{ steps.get-version.outputs.os-version }}-${{ steps.get-version.outputs.r-version }}-${{ inputs.cache-version }}-${{ hashFiles('renv.lock') }}
@ -589,7 +587,7 @@ whenever possible:
## Rust - Cargo
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
@ -604,7 +602,7 @@ whenever possible:
```yaml
- name: Cache SBT
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: |
~/.ivy2/cache
@ -615,7 +613,7 @@ whenever possible:
## Swift, Objective-C - Carthage
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: Carthage
key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
@ -626,7 +624,7 @@ whenever possible:
## Swift, Objective-C - CocoaPods
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
@ -637,7 +635,7 @@ whenever possible:
## Swift - Swift Package Manager
```yaml
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: .build
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
@ -652,42 +650,10 @@ env:
MINT_PATH: .mint/lib
MINT_LINK_PATH: .mint/bin
steps:
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: .mint
key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }}
restore-keys: |
${{ runner.os }}-mint-
```
## * - Bazel
[`bazelisk`](https://github.com/bazelbuild/bazelisk) does not have be to separately downloaded and installed because it's already included in GitHub's `ubuntu-latest` and `macos-latest` base images.
### Linux
```yaml
- name: Cache Bazel
uses: actions/cache@v4
with:
path: |
~/.cache/bazel
key: ${{ runner.os }}-bazel-${{ hashFiles('.bazelversion', '.bazelrc', 'WORKSPACE', 'WORKSPACE.bazel', 'MODULE.bazel') }}
restore-keys: |
${{ runner.os }}-bazel-
- run: bazelisk test //...
```
### macOS
```yaml
- name: Cache Bazel
uses: actions/cache@v4
with:
path: |
/private/var/tmp/_bazel_runner/
key: ${{ runner.os }}-bazel-${{ hashFiles('.bazelversion', '.bazelrc', 'WORKSPACE', 'WORKSPACE.bazel', 'MODULE.bazel') }}
restore-keys: |
${{ runner.os }}-bazel-
- run: bazelisk test //...
```

1451
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "cache",
"version": "4.0.2",
"version": "3.2.5",
"private": true,
"description": "Cache dependencies and build outputs",
"main": "dist/restore/index.js",
@ -23,7 +23,7 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^3.2.3",
"@actions/cache": "^3.1.3",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/io": "^1.1.2"
@ -34,7 +34,7 @@
"@types/node": "^16.18.3",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"@vercel/ncc": "^0.38.1",
"@zeit/ncc": "^0.20.5",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",

View File

@ -9,8 +9,7 @@ The restore action restores a cache. It works similarly to the `cache` action ex
* `key` - An explicit key for a cache entry. See [creating a cache key](../README.md#creating-a-cache-key).
* `path` - A list of files, directories, and wildcard patterns to restore. See [`@actions/glob`](https://github.com/actions/toolkit/tree/main/packages/glob) for supported patterns.
* `restore-keys` - An ordered list of prefix-matched keys to use for restoring stale cache if no cache hit occurred for key.
* `fail-on-cache-miss` - Fail the workflow if cache entry is not found. Default: `false`
* `lookup-only` - If true, only checks if cache entry exists and skips download. Default: `false`
* `fail-on-cache-miss` - Fail the workflow if cache entry is not found. Default: false
### Outputs
@ -23,7 +22,7 @@ The restore action restores a cache. It works similarly to the `cache` action ex
### Environment Variables
* `SEGMENT_DOWNLOAD_TIMEOUT_MINS` - Segment download timeout (in minutes, default `10`) to abort download of the segment if not completed in the defined number of minutes. [Read more](https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout)
* `SEGMENT_DOWNLOAD_TIMEOUT_MINS` - Segment download timeout (in minutes, default `60`) to abort download of the segment if not completed in the defined number of minutes. [Read more](https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout)
## Use cases
@ -35,9 +34,9 @@ If you are using separate jobs to create and save your cache(s) to be reused by
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/cache/restore@v4
- uses: actions/cache/restore@v3
id: cache
with:
path: path/to/dependencies
@ -64,12 +63,12 @@ In case of multi-module projects, where the built artifact of one project needs
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Build
run: /build-parent-module.sh
- uses: actions/cache/save@v4
- uses: actions/cache/save@v3
id: cache
with:
path: path/to/dependencies
@ -80,9 +79,9 @@ steps:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/cache/restore@v4
- uses: actions/cache/restore@v3
id: cache
with:
path: path/to/dependencies
@ -107,9 +106,9 @@ To fail if there is no cache hit for the primary key, leave `restore-keys` empty
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/cache/restore@v4
- uses: actions/cache/restore@v3
id: cache
with:
path: path/to/dependencies

View File

@ -9,7 +9,7 @@ inputs:
description: 'An explicit key for restoring the cache'
required: true
restore-keys:
description: 'An ordered multiline string listing the prefix-matched keys, that are used for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
description: 'An ordered list of keys to use for restoring stale cache if no cache hit occurred for key. Note `cache-hit` returns false in this case.'
required: false
enableCrossOsArchive:
description: 'An optional boolean when enabled, allows windows runners to restore caches that were saved on other platforms'
@ -19,10 +19,6 @@ inputs:
description: 'Fail the workflow if cache entry is not found'
default: 'false'
required: false
lookup-only:
description: 'Check if a cache entry exists for the given input(s) (key, restore-keys) without downloading the cache'
default: 'false'
required: false
outputs:
cache-hit:
description: 'A boolean value to indicate an exact match was found for the primary key'
@ -31,7 +27,7 @@ outputs:
cache-matched-key:
description: 'Key of the cache that was restored, it could either be the primary key on cache-hit or a partial/complete match of one of the restore keys'
runs:
using: 'node20'
using: 'node16'
main: '../dist/restore-only/index.js'
branding:
icon: 'archive'

View File

@ -23,7 +23,7 @@ If you are using separate jobs for generating common artifacts and sharing them
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Install Dependencies
run: /install.sh
@ -31,7 +31,7 @@ steps:
- name: Build artifacts
run: /build.sh
- uses: actions/cache/save@v4
- uses: actions/cache/save@v3
id: cache
with:
path: path/to/dependencies
@ -47,7 +47,7 @@ Let's say we have a restore step that computes a key at runtime.
#### Restore a cache
```yaml
uses: actions/cache/restore@v4
uses: actions/cache/restore@v3
id: restore-cache
with:
key: cache-${{ hashFiles('**/lockfiles') }}
@ -55,7 +55,7 @@ with:
#### Case 1 - Where a user would want to reuse the key as it is
```yaml
uses: actions/cache/save@v4
uses: actions/cache/save@v3
with:
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
```
@ -63,7 +63,7 @@ with:
#### Case 2 - Where the user would want to re-evaluate the key
```yaml
uses: actions/cache/save@v4
uses: actions/cache/save@v3
with:
key: npm-cache-${{hashfiles(package-lock.json)}}
```
@ -74,13 +74,13 @@ There are instances where some flaky test cases would fail the entire workflow a
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
.
. // restore if need be
.
- name: Build
run: /build.sh
- uses: actions/cache/save@v4
- uses: actions/cache/save@v3
if: always() // or any other condition to invoke the save action
with:
path: path/to/dependencies

View File

@ -16,7 +16,7 @@ inputs:
default: 'false'
required: false
runs:
using: 'node20'
using: 'node16'
main: '../dist/save-only/index.js'
branding:
icon: 'archive'

View File

@ -4,8 +4,7 @@ export enum Inputs {
RestoreKeys = "restore-keys", // Input for cache, restore action
UploadChunkSize = "upload-chunk-size", // Input for cache, save action
EnableCrossOsArchive = "enableCrossOsArchive", // Input for cache, restore, save action
FailOnCacheMiss = "fail-on-cache-miss", // Input for cache, restore action
LookupOnly = "lookup-only" // Input for cache, restore action
FailOnCacheMiss = "fail-on-cache-miss" // Input for cache, restore action
}
export enum Outputs {

View File

@ -1,3 +1,10 @@
import { restoreRun } from "./restoreImpl";
import restoreImpl from "./restoreImpl";
import { StateProvider } from "./stateProvider";
restoreRun(true);
async function run(): Promise<void> {
await restoreImpl(new StateProvider());
}
run();
export default run;

View File

@ -2,16 +2,11 @@ import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { Events, Inputs, Outputs, State } from "./constants";
import {
IStateProvider,
NullStateProvider,
StateProvider
} from "./stateProvider";
import { IStateProvider } from "./stateProvider";
import * as utils from "./utils/actionUtils";
export async function restoreImpl(
stateProvider: IStateProvider,
earlyExit?: boolean | undefined
async function restoreImpl(
stateProvider: IStateProvider
): Promise<string | undefined> {
try {
if (!utils.isCacheFeatureAvailable()) {
@ -40,18 +35,16 @@ export async function restoreImpl(
Inputs.EnableCrossOsArchive
);
const failOnCacheMiss = utils.getInputAsBool(Inputs.FailOnCacheMiss);
const lookupOnly = utils.getInputAsBool(Inputs.LookupOnly);
const cacheKey = await cache.restoreCache(
cachePaths,
primaryKey,
restoreKeys,
{ lookupOnly: lookupOnly },
{},
enableCrossOsArchive
);
if (!cacheKey) {
core.setOutput(Outputs.CacheHit, false.toString());
if (failOnCacheMiss) {
throw new Error(
`Failed to restore cache entry. Exiting as fail-on-cache-miss is set. Input key: ${primaryKey}`
@ -63,6 +56,7 @@ export async function restoreImpl(
...restoreKeys
].join(", ")}`
);
return;
}
@ -75,45 +69,12 @@ export async function restoreImpl(
);
core.setOutput(Outputs.CacheHit, isExactKeyMatch.toString());
if (lookupOnly) {
core.info(`Cache found and can be restored from key: ${cacheKey}`);
} else {
core.info(`Cache restored from key: ${cacheKey}`);
}
core.info(`Cache restored from key: ${cacheKey}`);
return cacheKey;
} catch (error: unknown) {
core.setFailed((error as Error).message);
if (earlyExit) {
process.exit(1);
}
}
}
async function run(
stateProvider: IStateProvider,
earlyExit: boolean | undefined
): Promise<void> {
await restoreImpl(stateProvider, earlyExit);
// node will stay alive if any promises are not resolved,
// which is a possibility if HTTP requests are dangling
// due to retries or timeouts. We know that if we got here
// that all promises that we care about have successfully
// resolved, so simply exit with success.
if (earlyExit) {
process.exit(0);
}
}
export async function restoreOnlyRun(
earlyExit?: boolean | undefined
): Promise<void> {
await run(new NullStateProvider(), earlyExit);
}
export async function restoreRun(
earlyExit?: boolean | undefined
): Promise<void> {
await run(new StateProvider(), earlyExit);
}
export default restoreImpl;

View File

@ -1,3 +1,10 @@
import { restoreOnlyRun } from "./restoreImpl";
import restoreImpl from "./restoreImpl";
import { NullStateProvider } from "./stateProvider";
restoreOnlyRun(true);
async function run(): Promise<void> {
await restoreImpl(new NullStateProvider());
}
run();
export default run;

View File

@ -1,3 +1,10 @@
import { saveRun } from "./saveImpl";
import saveImpl from "./saveImpl";
import { StateProvider } from "./stateProvider";
saveRun(true);
async function run(): Promise<void> {
await saveImpl(new StateProvider());
}
run();
export default run;

View File

@ -2,11 +2,7 @@ import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { Events, Inputs, State } from "./constants";
import {
IStateProvider,
NullStateProvider,
StateProvider
} from "./stateProvider";
import { IStateProvider } from "./stateProvider";
import * as utils from "./utils/actionUtils";
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
@ -14,9 +10,7 @@ import * as utils from "./utils/actionUtils";
// throw an uncaught exception. Instead of failing this action, just warn.
process.on("uncaughtException", e => utils.logWarning(e.message));
export async function saveImpl(
stateProvider: IStateProvider
): Promise<number | void> {
async function saveImpl(stateProvider: IStateProvider): Promise<number | void> {
let cacheId = -1;
try {
if (!utils.isCacheFeatureAvailable()) {
@ -78,47 +72,4 @@ export async function saveImpl(
return cacheId;
}
export async function saveOnlyRun(
earlyExit?: boolean | undefined
): Promise<void> {
try {
const cacheId = await saveImpl(new NullStateProvider());
if (cacheId === -1) {
core.warning(`Cache save failed.`);
}
} catch (err) {
console.error(err);
if (earlyExit) {
process.exit(1);
}
}
// node will stay alive if any promises are not resolved,
// which is a possibility if HTTP requests are dangling
// due to retries or timeouts. We know that if we got here
// that all promises that we care about have successfully
// resolved, so simply exit with success.
if (earlyExit) {
process.exit(0);
}
}
export async function saveRun(earlyExit?: boolean | undefined): Promise<void> {
try {
await saveImpl(new StateProvider());
} catch (err) {
console.error(err);
if (earlyExit) {
process.exit(1);
}
}
// node will stay alive if any promises are not resolved,
// which is a possibility if HTTP requests are dangling
// due to retries or timeouts. We know that if we got here
// that all promises that we care about have successfully
// resolved, so simply exit with success.
if (earlyExit) {
process.exit(0);
}
}
export default saveImpl;

View File

@ -1,3 +1,15 @@
import { saveOnlyRun } from "./saveImpl";
import * as core from "@actions/core";
saveOnlyRun(true);
import saveImpl from "./saveImpl";
import { NullStateProvider } from "./stateProvider";
async function run(): Promise<void> {
const cacheId = await saveImpl(new NullStateProvider());
if (cacheId === -1) {
core.warning(`Cache save failed.`);
}
}
run();
export default run;

View File

@ -15,7 +15,6 @@ interface CacheInput {
restoreKeys?: string[];
enableCrossOsArchive?: boolean;
failOnCacheMiss?: boolean;
lookupOnly?: boolean;
}
export function setInputs(input: CacheInput): void {
@ -30,8 +29,6 @@ export function setInputs(input: CacheInput): void {
);
input.failOnCacheMiss !== undefined &&
setInput(Inputs.FailOnCacheMiss, input.failOnCacheMiss.toString());
input.lookupOnly !== undefined &&
setInput(Inputs.LookupOnly, input.lookupOnly.toString());
}
export function clearInputs(): void {
@ -41,5 +38,4 @@ export function clearInputs(): void {
delete process.env[getInputName(Inputs.UploadChunkSize)];
delete process.env[getInputName(Inputs.EnableCrossOsArchive)];
delete process.env[getInputName(Inputs.FailOnCacheMiss)];
delete process.env[getInputName(Inputs.LookupOnly)];
}

View File

@ -1,45 +1,35 @@
# Tips and workarounds
## Cache segment restore timeout
A cache gets downloaded in multiple segments of fixed sizes (`1GB` for a `32-bit` runner and `2GB` for a `64-bit` runner). Sometimes, a segment download gets stuck which causes the workflow job to be stuck forever and fail. Version `v3.0.8` of `actions/cache` introduces a segment download timeout. The segment download timeout will allow the segment download to get aborted and hence allow the job to proceed with a cache miss.
Default value of this timeout is 10 minutes and can be customized by specifying an [environment variable](https://docs.github.com/en/actions/learn-github-actions/environment-variables) named `SEGMENT_DOWNLOAD_TIMEOUT_MINS` with timeout value in minutes.
Default value of this timeout is 60 minutes and can be customized by specifying an [environment variable](https://docs.github.com/en/actions/learn-github-actions/environment-variables) named `SEGMENT_DOWNLOAD_TIMEOUT_MINS` with timeout value in minutes.
## Update a cache
A cache today is immutable and cannot be updated. But some use cases require the cache to be saved even though there was a "hit" during restore. To do so, use a `key` which is unique for every run and use `restore-keys` to restore the nearest cache. For example:
```yaml
- name: update cache on every commit
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: prime-numbers
key: primes-${{ runner.os }}-${{ github.run_id }} # Can use time based key as well
restore-keys: |
primes-${{ runner.os }}
```
```
Please note that this will create a new cache on every run and hence will consume the cache [quota](./README.md#cache-limits).
## Use cache across feature branches
Reusing cache across feature branches is not allowed today to provide cache [isolation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache). However if both feature branches are from the default branch, a good way to achieve this is to ensure that the default branch has a cache. This cache will then be consumable by both feature branches.
## Cross OS cache
From `v3.2.3` cache is cross-os compatible when `enableCrossOsArchive` input is passed as true. This means that a cache created on `ubuntu-latest` or `mac-latest` can be used by `windows-latest` and vice versa, provided the workflow which runs on `windows-latest` have input `enableCrossOsArchive` as true. This is useful to cache dependencies which are independent of the runner platform. This will help reduce the consumption of the cache quota and help build for multiple platforms from the same cache. Things to keep in mind while using this feature:
- Only cache files that are compatible across OSs.
- Caching symlinks might cause issues while restoring them as they behave differently on different OSs.
- Be mindful when caching files from outside your github workspace directory as the directory is located at different places across OS.
- Avoid using directory pointers such as `${{ github.workspace }}` or `~` (home) which eventually evaluate to an absolute path that does not match across OSs.
- Only cache those files which are compatible across OSs.
- Caching symlinks might cause issues while restoration as they work differently on different OSs.
- Only cache files from within your github workspace directory.
- Avoid using directory pointers such as `${{ github.workspace }}` or `~` (home) which eventually evaluate to an absolute path and will not match across OSs.
## Force deletion of caches overriding default cache eviction policy
Caches have [branch scope restriction](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache) in place. This means that if caches for a specific branch are using a lot of storage quota, it may result into more frequently used caches from `default` branch getting thrashed. For example, if there are many pull requests happening on a repo and are creating caches, these cannot be used in default branch scope but will still occupy a lot of space till they get cleaned up by [eviction policy](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy). But sometime we want to clean them up on a faster cadence so as to ensure default branch is not thrashing. In order to achieve this, [gh-actions-cache cli](https://github.com/actions/gh-actions-cache/) can be used to delete caches for specific branches.
This workflow uses `gh-actions-cache` to delete all the caches created by a branch.
This workflow uses `gh-actions-cache` to delete all the caches created by a branch.
<details>
<summary>Example</summary>
@ -54,14 +44,9 @@ on:
jobs:
cleanup:
runs-on: ubuntu-latest
permissions:
# `actions:write` permission is required to delete caches
# See also: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-a-github-actions-cache-for-a-repository-using-a-cache-id
actions: write
contents: read
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Cleanup
run: |
@ -84,5 +69,4 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
</details>