mirror of
https://github.com/gradle/actions.git
synced 2026-10-16 19:57:12 +08:00
Merge pull request #67 from gradle/dd/v15
Allow caching to be enabled read-only
This commit is contained in:
5 files changed
+61
-7
No files matched your search
@@ -7,7 +7,22 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
basic-build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Build using Gradle wrapper
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
build-root-directory: __tests__/samples/basic
|
||||||
|
arguments: test
|
||||||
|
|
||||||
gradle-execution:
|
gradle-execution:
|
||||||
|
needs: basic-build
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
@@ -18,11 +33,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Test use Gradle wrapper
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
build-root-directory: __tests__/samples/basic
|
|
||||||
arguments: test
|
|
||||||
- name: Test use defined Gradle version
|
- name: Test use defined Gradle version
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
@@ -49,6 +59,7 @@ jobs:
|
|||||||
arguments: help
|
arguments: help
|
||||||
|
|
||||||
dependencies-cache:
|
dependencies-cache:
|
||||||
|
needs: basic-build
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
@@ -64,6 +75,7 @@ jobs:
|
|||||||
dependencies-cache-enabled: true
|
dependencies-cache-enabled: true
|
||||||
|
|
||||||
configuration-cache:
|
configuration-cache:
|
||||||
|
needs: basic-build
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
@@ -80,8 +92,26 @@ jobs:
|
|||||||
dependencies-cache-enabled: true
|
dependencies-cache-enabled: true
|
||||||
# Configuration cache requires dependencies cache, since it assumes dependencies are already downloaded.
|
# Configuration cache requires dependencies cache, since it assumes dependencies are already downloaded.
|
||||||
|
|
||||||
|
cache-read-only:
|
||||||
|
needs: basic-build
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Test cache-read-only
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
build-root-directory: __tests__/samples/basic
|
||||||
|
arguments: test --no-daemon
|
||||||
|
dependencies-cache-enabled: true
|
||||||
|
configuration-cache-enabled: true
|
||||||
|
cache-read-only: true
|
||||||
|
|
||||||
failures: # These build invocations are informational only, and are expected to fail
|
failures: # These build invocations are informational only, and are expected to fail
|
||||||
|
needs: basic-build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ The distributions cache is simple and can't be configured further.
|
|||||||
The dependencies and configuration cache will compute a cache key in a best effort manner.
|
The dependencies and configuration cache will compute a cache key in a best effort manner.
|
||||||
Keep reading to learn how to better control how they work.
|
Keep reading to learn how to better control how they work.
|
||||||
|
|
||||||
Note that enabling configuration cache without thee dependencies cache is not permitted, since a hit in the configuration cache assumes that dependencies are already present in the local dependencies cache.
|
Note that enabling configuration cache without the dependencies cache is not permitted, since a hit in the configuration cache assumes that dependencies are already present in the local dependencies cache.
|
||||||
|
|
||||||
### Configuring the dependencies and configuration caches
|
### Configuring the dependencies and configuration caches
|
||||||
|
|
||||||
@@ -187,6 +187,18 @@ dependencies-cache-key: gradle/dependency-locks/**
|
|||||||
dependencies-cache-exact: true
|
dependencies-cache-exact: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Using the caches read-only
|
||||||
|
|
||||||
|
Cache storage space is limited for GitHub actions, and writing new cache entries can trigger the deletion of exising entries.
|
||||||
|
In some circumstances, it makes sense for a Gradle invocation to use any existing cache entries but not to write and changes back.
|
||||||
|
For example, you may want to write cache entries for builds on your `main` branch, but not for any PR build invocations.
|
||||||
|
|
||||||
|
Use the following configuration to avoid writing cache entries for the action invocation:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
cache-read-only: true
|
||||||
|
```
|
||||||
|
|
||||||
## Build scans
|
## Build scans
|
||||||
|
|
||||||
If your build publishes a [build scan](https://gradle.com/build-scans/) the `gradle-build-action` action will emit the link to the published build scan as an output named `build-scan-url`.
|
If your build publishes a [build scan](https://gradle.com/build-scans/) the `gradle-build-action` action will emit the link to the published build scan as an output named `build-scan-url`.
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ inputs:
|
|||||||
description: Whether to restore only if exact match, default to 'false'
|
description: Whether to restore only if exact match, default to 'false'
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
|
cache-read-only:
|
||||||
|
description: When 'true', existing entries will be read from the cache but no entries will be written
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
build-scan-url:
|
build-scan-url:
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
module.exports=function(e,t){"use strict";var n={};function __webpack_require__(t){if(n[t]){return n[t].exports}var i=n[t]={i:t,l:false,exports:{}};var a=true;try{e[t].call(i.exports,i,i.exports,__webpack_require__);a=false}finally{if(a)delete n[t]}i.l=true;return i.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(878)}return startup()}([,function(e,t,n){"use strict";var i=this&&this.__createBinding||(Object.create?function(e,t,n,i){if(i===undefined)i=n;Object.defineProperty(e,i,{enumerable:true,get:function(){return t[n]}})}:function(e,t,n,i){if(i===undefined)i=n;e[i]=t[n]});var a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(n!=="default"&&Object.hasOwnProperty.call(e,n))i(t,e,n);a(t,e);return t};var o=this&&this.__awaiter||function(e,t,n,i){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function fulfilled(e){try{step(i.next(e))}catch(e){a(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){a(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});t.findInPath=t.which=t.mkdirP=t.rmRF=t.mv=t.cp=void 0;const s=n(357);const c=r(n(129));const u=r(n(622));const l=n(669);const p=r(n(672));const m=l.promisify(c.exec);const d=l.promisify(c.execFile);function cp(e,t,n={}){return o(this,void 0,void 0,function*(){const{force:i,recursive:a,copySourceDirectory:r}=readCopyOptions(n);const o=(yield p.exists(t))?yield p.stat(t):null;if(o&&o.isFile()&&!i){return}const s=o&&o.isDirectory()&&r?u.join(t,u.basename(e)):t;if(!(yield p.exists(e))){throw new Error(`no such file or directory: ${e}`)}const c=yield p.stat(e);if(c.isDirectory()){if(!a){throw new Error(`Failed to copy. ${e} is a directory, but tried to copy without recursive flag.`)}else{yield cpDirRecursive(e,s,0,i)}}else{if(u.relative(e,s)===""){throw new Error(`'${s}' and '${e}' are the same file`)}yield copyFile(e,s,i)}})}t.cp=cp;function mv(e,t,n={}){return o(this,void 0,void 0,function*(){if(yield p.exists(t)){let i=true;if(yield p.isDirectory(t)){t=u.join(t,u.basename(e));i=yield p.exists(t)}if(i){if(n.force==null||n.force){yield rmRF(t)}else{throw new Error("Destination already exists")}}}yield mkdirP(u.dirname(t));yield p.rename(e,t)})}t.mv=mv;function rmRF(e){return o(this,void 0,void 0,function*(){if(p.IS_WINDOWS){if(/[*"<>|]/.test(e)){throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows')}try{const t=p.getCmdPath();if(yield p.isDirectory(e,true)){yield m(`${t} /s /c "rd /s /q "%inputPath%""`,{env:{inputPath:e}})}else{yield m(`${t} /s /c "del /f /a "%inputPath%""`,{env:{inputPath:e}})}}catch(e){if(e.code!=="ENOENT")throw e}try{yield p.unlink(e)}catch(e){if(e.code!=="ENOENT")throw e}}else{let t=false;try{t=yield p.isDirectory(e)}catch(e){if(e.code!=="ENOENT")throw e;return}if(t){yield d(`rm`,[`-rf`,`${e}`])}else{yield p.unlink(e)}}})}t.rmRF=rmRF;function mkdirP(e){return o(this,void 0,void 0,function*(){s.ok(e,"a path argument must be provided");yield p.mkdir(e,{recursive:true})})}t.mkdirP=mkdirP;function which(e,t){return o(this,void 0,void 0,function*(){if(!e){throw new Error("parameter 'tool' is required")}if(t){const t=yield which(e,false);if(!t){if(p.IS_WINDOWS){throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`)}else{throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`)}}return t}const n=yield findInPath(e);if(n&&n.length>0){return n[0]}return""})}t.which=which;function findInPath(e){return o(this,void 0,void 0,function*(){if(!e){throw new Error("parameter 'tool' is required")}const t=[];if(p.IS_WINDOWS&&process.env["PATHEXT"]){for(const e of process.env["PATHEXT"].split(u.delimiter)){if(e){t.push(e)}}}if(p.isRooted(e)){const n=yield p.tryGetExecutablePath(e,t);if(n){return[n]}return[]}if(e.includes(u.sep)){return[]}const n=[];if(process.env.PATH){for(const e of process.env.PATH.split(u.delimiter)){if(e){n.push(e)}}}const i=[];for(const a of n){const n=yield p.tryGetExecutablePath(u.join(a,e),t);if(n){i.push(n)}}return i})}t.findInPath=findInPath;function readCopyOptions(e){const t=e.force==null?true:e.force;const n=Boolean(e.recursive);const i=e.copySourceDirectory==null?true:Boolean(e.copySourceDirectory);return{force:t,recursive:n,copySourceDirectory:i}}function cpDirRecursive(e,t,n,i){return o(this,voLine truncated
|
module.exports=function(e,t){"use strict";var n={};function __webpack_require__(t){if(n[t]){return n[t].exports}var i=n[t]={i:t,l:false,exports:{}};var a=true;try{e[t].call(i.exports,i,i.exports,__webpack_require__);a=false}finally{if(a)delete n[t]}i.l=true;return i.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(878)}return startup()}([,function(e,t,n){"use strict";var i=this&&this.__createBinding||(Object.create?function(e,t,n,i){if(i===undefined)i=n;Object.defineProperty(e,i,{enumerable:true,get:function(){return t[n]}})}:function(e,t,n,i){if(i===undefined)i=n;e[i]=t[n]});var a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(n!=="default"&&Object.hasOwnProperty.call(e,n))i(t,e,n);a(t,e);return t};var o=this&&this.__awaiter||function(e,t,n,i){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function fulfilled(e){try{step(i.next(e))}catch(e){a(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){a(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});t.findInPath=t.which=t.mkdirP=t.rmRF=t.mv=t.cp=void 0;const s=n(357);const c=r(n(129));const u=r(n(622));const l=n(669);const p=r(n(672));const m=l.promisify(c.exec);const d=l.promisify(c.execFile);function cp(e,t,n={}){return o(this,void 0,void 0,function*(){const{force:i,recursive:a,copySourceDirectory:r}=readCopyOptions(n);const o=(yield p.exists(t))?yield p.stat(t):null;if(o&&o.isFile()&&!i){return}const s=o&&o.isDirectory()&&r?u.join(t,u.basename(e)):t;if(!(yield p.exists(e))){throw new Error(`no such file or directory: ${e}`)}const c=yield p.stat(e);if(c.isDirectory()){if(!a){throw new Error(`Failed to copy. ${e} is a directory, but tried to copy without recursive flag.`)}else{yield cpDirRecursive(e,s,0,i)}}else{if(u.relative(e,s)===""){throw new Error(`'${s}' and '${e}' are the same file`)}yield copyFile(e,s,i)}})}t.cp=cp;function mv(e,t,n={}){return o(this,void 0,void 0,function*(){if(yield p.exists(t)){let i=true;if(yield p.isDirectory(t)){t=u.join(t,u.basename(e));i=yield p.exists(t)}if(i){if(n.force==null||n.force){yield rmRF(t)}else{throw new Error("Destination already exists")}}}yield mkdirP(u.dirname(t));yield p.rename(e,t)})}t.mv=mv;function rmRF(e){return o(this,void 0,void 0,function*(){if(p.IS_WINDOWS){if(/[*"<>|]/.test(e)){throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows')}try{const t=p.getCmdPath();if(yield p.isDirectory(e,true)){yield m(`${t} /s /c "rd /s /q "%inputPath%""`,{env:{inputPath:e}})}else{yield m(`${t} /s /c "del /f /a "%inputPath%""`,{env:{inputPath:e}})}}catch(e){if(e.code!=="ENOENT")throw e}try{yield p.unlink(e)}catch(e){if(e.code!=="ENOENT")throw e}}else{let t=false;try{t=yield p.isDirectory(e)}catch(e){if(e.code!=="ENOENT")throw e;return}if(t){yield d(`rm`,[`-rf`,`${e}`])}else{yield p.unlink(e)}}})}t.rmRF=rmRF;function mkdirP(e){return o(this,void 0,void 0,function*(){s.ok(e,"a path argument must be provided");yield p.mkdir(e,{recursive:true})})}t.mkdirP=mkdirP;function which(e,t){return o(this,void 0,void 0,function*(){if(!e){throw new Error("parameter 'tool' is required")}if(t){const t=yield which(e,false);if(!t){if(p.IS_WINDOWS){throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`)}else{throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`)}}return t}const n=yield findInPath(e);if(n&&n.length>0){return n[0]}return""})}t.which=which;function findInPath(e){return o(this,void 0,void 0,function*(){if(!e){throw new Error("parameter 'tool' is required")}const t=[];if(p.IS_WINDOWS&&process.env["PATHEXT"]){for(const e of process.env["PATHEXT"].split(u.delimiter)){if(e){t.push(e)}}}if(p.isRooted(e)){const n=yield p.tryGetExecutablePath(e,t);if(n){return[n]}return[]}if(e.includes(u.sep)){return[]}const n=[];if(process.env.PATH){for(const e of process.env.PATH.split(u.delimiter)){if(e){n.push(e)}}}const i=[];for(const a of n){const n=yield p.tryGetExecutablePath(u.join(a,e),t);if(n){i.push(n)}}return i})}t.findInPath=findInPath;function readCopyOptions(e){const t=e.force==null?true:e.force;const n=Boolean(e.recursive);const i=e.copySourceDirectory==null?true:Boolean(e.copySourceDirectory);return{force:t,recursive:n,copySourceDirectory:i}}function cpDirRecursive(e,t,n,i){return o(this,voLine truncated
|
||||||
@@ -1,12 +1,20 @@
|
|||||||
|
import * as core from '@actions/core'
|
||||||
|
|
||||||
import * as cacheWrapper from './cache-wrapper'
|
import * as cacheWrapper from './cache-wrapper'
|
||||||
import * as cacheDependencies from './cache-dependencies'
|
import * as cacheDependencies from './cache-dependencies'
|
||||||
import * as cacheConfiguration from './cache-configuration'
|
import * as cacheConfiguration from './cache-configuration'
|
||||||
|
|
||||||
// Invoked by GitHub Actions
|
// Invoked by GitHub Actions
|
||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
|
if (isCacheReadOnly()) return
|
||||||
|
|
||||||
await cacheWrapper.cacheWrapperDist()
|
await cacheWrapper.cacheWrapperDist()
|
||||||
await cacheDependencies.cacheDependencies()
|
await cacheDependencies.cacheDependencies()
|
||||||
await cacheConfiguration.cacheConfiguration()
|
await cacheConfiguration.cacheConfiguration()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCacheReadOnly(): boolean {
|
||||||
|
return core.getBooleanInput('cache-read-only')
|
||||||
|
}
|
||||||
|
|
||||||
run()
|
run()
|
||||||
Reference in new issue
Block a user