diff --git a/README.md b/README.md index 9c56a6f..d2c137d 100644 --- a/README.md +++ b/README.md @@ -90,9 +90,11 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous clean: '' # Number of commits to fetch. 0 indicates all history for all branches and tags. - # Default: 1 fetch-depth: '' + # Date like `2days` or `1970-01-01`. Fetch a history after the specified time. + shallow-since: '' + # Whether to download Git-LFS files # Default: false lfs: '' diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts index b39d352..352db97 100644 --- a/__test__/git-auth-helper.test.ts +++ b/__test__/git-auth-helper.test.ts @@ -760,6 +760,7 @@ async function setup(testName: string): Promise { clean: true, commit: '', fetchDepth: 1, + shallowSince: '', lfs: false, submodules: false, nestedSubmodules: false, diff --git a/action.yml b/action.yml index 91d3982..c36189d 100644 --- a/action.yml +++ b/action.yml @@ -55,7 +55,8 @@ inputs: default: true fetch-depth: description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' - default: 1 + shallow-since: + description: 'Date like `2days` or `1970-01-01`. Fetch a history after the specified time.' lfs: description: 'Whether to download Git-LFS files' default: false diff --git a/adrs/0153-checkout-v2.md b/adrs/0153-checkout-v2.md index 74730c7..880f608 100644 --- a/adrs/0153-checkout-v2.md +++ b/adrs/0153-checkout-v2.md @@ -72,6 +72,8 @@ We want to take this opportunity to make behavioral changes, from v1. This docum fetch-depth: description: 'Number of commits to fetch. 0 indicates all history for all tags and branches.' default: 1 + shallow-since: + description: 'Date like `2days` or `1970-01-01`. Fetch a history after the specified time.' lfs: description: 'Whether to download Git-LFS files' default: false @@ -155,7 +157,7 @@ Fetch only the SHA being built and set depth=1. This significantly reduces the f If a SHA isn't available (e.g. multi repo), then fetch only the specified ref with depth=1. -The input `fetch-depth` can be used to control the depth. +The input `fetch-depth` and `shallow-since` can be used to control the depth. Note: - Fetching a single commit is supported by Git wire protocol version 2. The git client uses protocol version 0 by default. The desired protocol version can be overridden in the git config or on the fetch command line invocation (`-c protocol.version=2`). We will override on the fetch command line, for transparency. diff --git a/dist/index.js b/dist/index.js index 7155f1c..4b907a0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4229,7 +4229,7 @@ module.exports = require("punycode"); /***/ 215: /***/ (function(module) { -module.exports = {"name":"@octokit/rest","version":"16.43.1","publishConfig":{"access":"public"},"description":"GitHub REST API client for Node.js","keywords":["octokit","github","rest","api-client"],"author":"Gregor Martynus (https://github.com/gr2m)","contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"repository":"https://github.com/octokit/rest.js","dependencies":{"@octokit/auth-token":"^2.4.0","@octokit/plugin-paginate-rest":"^1.1.1","@octokit/plugin-request-log":"^1.0.0","@octokit/plugin-rest-endpoint-methods":"2.4.0","@octokit/request":"^5.2.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^4.0.0"},"devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/auth":"^1.1.1","@octokit/fixtures-server":"^5.0.6","@octokit/graphql":"^4.2.0","@types/node":"^13.1.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.1.0","cypress":"^3.0.0","glob":"^7.1.2","http-proxy-agent":"^4.0.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","lolex":"^5.1.2","mkdirp":"^1.0.0","mocha":"^7.0.1","mustache":"^4.0.0","nock":"^11.3.3","npm-run-all":"^4.1.2","nyc":"^15.0.0","prettier":"^1.14.2","proxy":"^1.0.0","semantic-release":"^17.0.0","sinon":"^8.0.0","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"types":"index.d.ts","scripts":{"coverage":"nyc report --reporter=html && open coverage/index.html","lint":"prettier --check '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json","lint:fix":"prettier --write '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json","pretest":"npm run -s lint","test":"nyc mocha test/mocha-node-setup.js \"test/*/**/*-test.js\"","test:browser":"cypress run --browser chrome","build":"npm-run-all build:*","build:ts":"npm run -s update-endpoints:typescript","prebuild:browser":"mkdirp dist/","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","update-endpoints":"npm-run-all update-endpoints:*","update-endpoints:fetch-json":"node scripts/update-endpoints/fetch-json","update-endpoints:typescript":"node scripts/update-endpoints/typescript","prevalidate:ts":"npm run -s build:ts","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","start-fixtures-server":"octokit-fixtures-server"},"license":"MIT","files":["index.js","index.d.ts","lib","plugins"],"nyc":{"ignore":["test"]},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.43.1.tgz","_integrity":"sha512-gfFKwRT/wFxq5qlNjnW2dh+qh74XgTQ2B179UX5K1HYCluioWj8Ndbgqw2PVqa1NnVJkGHp2ovMpVn/DImlmkw==","_from":"@octokit/rest@16.43.1"}; +module.exports = {"name":"@octokit/rest","version":"16.43.1","publishConfig":{"access":"public"},"description":"GitHub REST API client for Node.js","keywords":["octokit","github","rest","api-client"],"author":"Gregor Martynus (https://github.com/gr2m)","contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"repository":"https://github.com/octokit/rest.js","dependencies":{"@octokit/auth-token":"^2.4.0","@octokit/plugin-paginate-rest":"^1.1.1","@octokit/plugin-request-log":"^1.0.0","@octokit/plugin-rest-endpoint-methods":"2.4.0","@octokit/request":"^5.2.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^4.0.0"},"devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/auth":"^1.1.1","@octokit/fixtures-server":"^5.0.6","@octokit/graphql":"^4.2.0","@types/node":"^13.1.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.1.0","cypress":"^3.0.0","glob":"^7.1.2","http-proxy-agent":"^4.0.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","lolex":"^5.1.2","mkdirp":"^1.0.0","mocha":"^7.0.1","mustache":"^4.0.0","nock":"^11.3.3","npm-run-all":"^4.1.2","nyc":"^15.0.0","prettier":"^1.14.2","proxy":"^1.0.0","semantic-release":"^17.0.0","sinon":"^8.0.0","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"types":"index.d.ts","scripts":{"coverage":"nyc report --reporter=html && open coverage/index.html","lint":"prettier --check '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json","lint:fix":"prettier --write '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json","pretest":"npm run -s lint","test":"nyc mocha test/mocha-node-setup.js \"test/*/**/*-test.js\"","test:browser":"cypress run --browser chrome","build":"npm-run-all build:*","build:ts":"npm run -s update-endpoints:typescript","prebuild:browser":"mkdirp dist/","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","update-endpoints":"npm-run-all update-endpoints:*","update-endpoints:fetch-json":"node scripts/update-endpoints/fetch-json","update-endpoints:typescript":"node scripts/update-endpoints/typescript","prevalidate:ts":"npm run -s build:ts","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","start-fixtures-server":"octokit-fixtures-server"},"license":"MIT","files":["index.js","index.d.ts","lib","plugins"],"nyc":{"ignore":["test"]},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}]}; /***/ }), @@ -6951,14 +6951,17 @@ class GitCommandManager { return output.exitCode === 0; }); } - fetch(refSpec, fetchDepth) { + fetch(refSpec, fetchDepth, shallowSince) { return __awaiter(this, void 0, void 0, function* () { const args = ['-c', 'protocol.version=2', 'fetch']; if (!refSpec.some(x => x === refHelper.tagsRefSpec)) { args.push('--no-tags'); } args.push('--prune', '--progress', '--no-recurse-submodules'); - if (fetchDepth && fetchDepth > 0) { + if (shallowSince) { + args.push(`--shallow-since=${shallowSince}`); + } + else if (fetchDepth && fetchDepth > 0) { args.push(`--depth=${fetchDepth}`); } else if (fshelper.fileExistsSync(path.join(this.workingDirectory, '.git', 'shallow'))) { @@ -7088,13 +7091,16 @@ class GitCommandManager { yield this.execGit(args); }); } - submoduleUpdate(fetchDepth, recursive) { + submoduleUpdate(fetchDepth, recursive, shallowSince) { return __awaiter(this, void 0, void 0, function* () { const args = ['-c', 'protocol.version=2']; args.push('submodule', 'update', '--init', '--force'); if (fetchDepth > 0) { args.push(`--depth=${fetchDepth}`); } + if (shallowSince) { + args.push(`--shallow-since=${shallowSince}`); + } if (recursive) { args.push('--recursive'); } @@ -7386,7 +7392,7 @@ function getSource(settings) { } else { const refSpec = refHelper.getRefSpec(settings.ref, settings.commit); - yield git.fetch(refSpec, settings.fetchDepth); + yield git.fetch(refSpec, settings.fetchDepth, settings.shallowSince); } core.endGroup(); // Checkout info @@ -7415,7 +7421,7 @@ function getSource(settings) { // Checkout submodules core.startGroup('Fetching submodules'); yield git.submoduleSync(settings.nestedSubmodules); - yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules); + yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules, settings.shallowSince); yield git.submoduleForeach('git config --local gc.auto 0', settings.nestedSubmodules); core.endGroup(); // Persist credentials @@ -17122,12 +17128,18 @@ function getInputs() { // Clean result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE'; core.debug(`clean = ${result.clean}`); + if (core.getInput('fetch-depth') && core.getInput('shallow-since')) { + throw new Error('`fetch-depth` and `shallow-since` cannot be used at the same time'); + } // Fetch depth result.fetchDepth = Math.floor(Number(core.getInput('fetch-depth') || '1')); if (isNaN(result.fetchDepth) || result.fetchDepth < 0) { result.fetchDepth = 0; } core.debug(`fetch depth = ${result.fetchDepth}`); + // Shallow since + result.shallowSince = core.getInput('shallow-since'); + core.debug(`shallow since = ${result.shallowSince}`); // LFS result.lfs = (core.getInput('lfs') || 'false').toUpperCase() === 'TRUE'; core.debug(`lfs = ${result.lfs}`); diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts index 409a161..5db9c3f 100644 --- a/src/git-command-manager.ts +++ b/src/git-command-manager.ts @@ -24,7 +24,11 @@ export interface IGitCommandManager { globalConfig?: boolean ): Promise configExists(configKey: string, globalConfig?: boolean): Promise - fetch(refSpec: string[], fetchDepth?: number): Promise + fetch( + refSpec: string[], + fetchDepth?: number, + shallowSince?: string + ): Promise getDefaultBranch(repositoryUrl: string): Promise getWorkingDirectory(): string init(): Promise @@ -39,7 +43,11 @@ export interface IGitCommandManager { shaExists(sha: string): Promise submoduleForeach(command: string, recursive: boolean): Promise submoduleSync(recursive: boolean): Promise - submoduleUpdate(fetchDepth: number, recursive: boolean): Promise + submoduleUpdate( + fetchDepth: number, + recursive: boolean, + shallowSince?: string + ): Promise tagExists(pattern: string): Promise tryClean(): Promise tryConfigUnset(configKey: string, globalConfig?: boolean): Promise @@ -168,14 +176,20 @@ class GitCommandManager { return output.exitCode === 0 } - async fetch(refSpec: string[], fetchDepth?: number): Promise { + async fetch( + refSpec: string[], + fetchDepth?: number, + shallowSince?: string + ): Promise { const args = ['-c', 'protocol.version=2', 'fetch'] if (!refSpec.some(x => x === refHelper.tagsRefSpec)) { args.push('--no-tags') } args.push('--prune', '--progress', '--no-recurse-submodules') - if (fetchDepth && fetchDepth > 0) { + if (shallowSince) { + args.push(`--shallow-since=${shallowSince}`) + } else if (fetchDepth && fetchDepth > 0) { args.push(`--depth=${fetchDepth}`) } else if ( fshelper.fileExistsSync( @@ -310,12 +324,19 @@ class GitCommandManager { await this.execGit(args) } - async submoduleUpdate(fetchDepth: number, recursive: boolean): Promise { + async submoduleUpdate( + fetchDepth: number, + recursive: boolean, + shallowSince?: string + ): Promise { const args = ['-c', 'protocol.version=2'] args.push('submodule', 'update', '--init', '--force') if (fetchDepth > 0) { args.push(`--depth=${fetchDepth}`) } + if (shallowSince) { + args.push(`--shallow-since=${shallowSince}`) + } if (recursive) { args.push('--recursive') diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts index 42a12e0..b307f80 100644 --- a/src/git-source-provider.ts +++ b/src/git-source-provider.ts @@ -141,7 +141,7 @@ export async function getSource(settings: IGitSourceSettings): Promise { } } else { const refSpec = refHelper.getRefSpec(settings.ref, settings.commit) - await git.fetch(refSpec, settings.fetchDepth) + await git.fetch(refSpec, settings.fetchDepth, settings.shallowSince) } core.endGroup() @@ -181,7 +181,8 @@ export async function getSource(settings: IGitSourceSettings): Promise { await git.submoduleSync(settings.nestedSubmodules) await git.submoduleUpdate( settings.fetchDepth, - settings.nestedSubmodules + settings.nestedSubmodules, + settings.shallowSince ) await git.submoduleForeach( 'git config --local gc.auto 0', diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts index 2786222..6c7f5f6 100644 --- a/src/git-source-settings.ts +++ b/src/git-source-settings.ts @@ -34,6 +34,11 @@ export interface IGitSourceSettings { */ fetchDepth: number + /** + * The date which a history after is fetched + */ + shallowSince: string + /** * Indicates whether to fetch LFS objects */ diff --git a/src/input-helper.ts b/src/input-helper.ts index 4c05d6e..ad9d2b1 100644 --- a/src/input-helper.ts +++ b/src/input-helper.ts @@ -81,6 +81,12 @@ export function getInputs(): IGitSourceSettings { result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE' core.debug(`clean = ${result.clean}`) + if (core.getInput('fetch-depth') && core.getInput('shallow-since')) { + throw new Error( + '`fetch-depth` and `shallow-since` cannot be used at the same time' + ) + } + // Fetch depth result.fetchDepth = Math.floor(Number(core.getInput('fetch-depth') || '1')) if (isNaN(result.fetchDepth) || result.fetchDepth < 0) { @@ -88,6 +94,10 @@ export function getInputs(): IGitSourceSettings { } core.debug(`fetch depth = ${result.fetchDepth}`) + // Shallow since + result.shallowSince = core.getInput('shallow-since') + core.debug(`shallow since = ${result.shallowSince}`) + // LFS result.lfs = (core.getInput('lfs') || 'false').toUpperCase() === 'TRUE' core.debug(`lfs = ${result.lfs}`)