v2.4.0 - support local execution with act + allow tags (#40)

* Avoid code repetition with exec() and output listeners

* Improve behavior for new branches and when it's running in ACT

* Detect parent commit only if needed

* Fix parent commit detection for initial commit

* Improve logging

* Improve current ref detection

* Fix issue when base is a already fetched tag

* Fix issue when base is a already fetched tag

* Update README

* Document usage with act

* Use `git log` to get changes in latest commit

* Disable other output for `git log`

* get short name from base ref + improve loggig

* update CHANGELOG
This commit is contained in:
Michal Dorner 2020-09-30 00:32:49 +02:00 committed by GitHub
parent d9e86af7c0
commit ff5bb057bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 295 additions and 147 deletions

View File

@ -1,5 +1,13 @@
# Changelog
## v2.4.0
- [Support pushes of tags or when tag is used as base](https://github.com/dorny/paths-filter/pull/40)
- [Use git log to detect changes from PRs merge commit if token is not available](https://github.com/dorny/paths-filter/pull/40)
- [Support local execution with act](https://github.com/dorny/paths-filter/pull/40)
- [Improved processing of repository initial push](https://github.com/dorny/paths-filter/pull/40)
- [Improved processing of first push of new branch](https://github.com/dorny/paths-filter/pull/40)
## v2.3.0
- [Improved documentation](https://github.com/dorny/paths-filter/pull/37)
- [Change detection using git "three dot" diff](https://github.com/dorny/paths-filter/pull/35)

View File

@ -31,10 +31,14 @@ doesn't allow this because they doesn't work on a level of individual jobs or st
- Minimatch [dot](https://www.npmjs.com/package/minimatch#dot) option is set to true.
Globbing will match also paths where file or folder name starts with a dot.
- It's recommended to quote your path expressions with `'` or `"`. Otherwise you will get an error if it starts with `*`.
- Local execution with [act](https://github.com/nektos/act) works only with alternative runner image. Default runner doesn't have `git` binary.
- Use: `act -P ubuntu-latest=nektos/act-environments-ubuntu:18.04`
# What's New
- Support for tag pushes and tags as a base reference
- Fixes for various edge cases when event payload is incomplete
- Supports local execution with [act](https://github.com/nektos/act)
- Fixed behavior of feature branch workflow:
- Detects only changes introduced by feature branch. Later modifications on base branch are ignored.
- Filter by type of file change:
@ -68,7 +72,7 @@ For more information see [CHANGELOG](https://github.com/actions/checkout/blob/ma
# Filters syntax is documented by example - see examples section.
filters: ''
# Branch against which the changes will be detected.
# Branch or tag against which the changes will be detected.
# If it references same branch it was pushed to,
# changes are detected against the most recent commit before the push.
# Otherwise it uses git merge-base to find best common ancestor between

View File

@ -17,19 +17,13 @@ describe('parsing output of the git diff command', () => {
})
describe('git utility function tests (those not invoking git)', () => {
test('Detects if ref references a tag', () => {
expect(git.isTagRef('refs/tags/v1.0')).toBeTruthy()
expect(git.isTagRef('refs/heads/master')).toBeFalsy()
expect(git.isTagRef('master')).toBeFalsy()
})
test('Trims "refs/" from ref', () => {
expect(git.trimRefs('refs/heads/master')).toBe('heads/master')
expect(git.trimRefs('heads/master')).toBe('heads/master')
expect(git.trimRefs('master')).toBe('master')
})
test('Trims "refs/" and "heads/" from ref', () => {
expect(git.trimRefsHeads('refs/heads/master')).toBe('master')
expect(git.trimRefsHeads('heads/master')).toBe('master')
expect(git.trimRefsHeads('master')).toBe('master')
expect(git.getShortName('refs/heads/master')).toBe('master')
expect(git.getShortName('heads/master')).toBe('heads/master')
expect(git.getShortName('master')).toBe('master')
expect(git.getShortName('refs/tags/v1')).toBe('v1')
expect(git.getShortName('tags/v1')).toBe('tags/v1')
expect(git.getShortName('v1')).toBe('v1')
})
})

212
dist/index.js vendored
View File

@ -3807,27 +3807,20 @@ var __importStar = (this && this.__importStar) || function (mod) {
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.trimRefsHeads = exports.trimRefs = exports.isTagRef = exports.listAllFilesAsAdded = exports.parseGitDiffOutput = exports.getChangesSinceRef = exports.getChangesAgainstSha = exports.NULL_SHA = void 0;
const exec_1 = __webpack_require__(986);
exports.getShortName = exports.getCurrentRef = exports.listAllFilesAsAdded = exports.parseGitDiffOutput = exports.getChangesSinceMergeBase = exports.getChanges = exports.getChangesInLastCommit = exports.NULL_SHA = void 0;
const exec_1 = __importDefault(__webpack_require__(807));
const core = __importStar(__webpack_require__(470));
const file_1 = __webpack_require__(258);
exports.NULL_SHA = '0000000000000000000000000000000000000000';
async function getChangesAgainstSha(sha) {
// Fetch single commit
core.startGroup(`Fetching ${sha} from origin`);
await exec_1.exec('git', ['fetch', '--depth=1', '--no-tags', 'origin', sha]);
core.endGroup();
// Get differences between sha and HEAD
core.startGroup(`Change detection ${sha}..HEAD`);
async function getChangesInLastCommit() {
core.startGroup(`Change detection in last commit`);
let output = '';
try {
// Two dots '..' change detection - directly compares two versions
await exec_1.exec('git', ['diff', '--no-renames', '--name-status', '-z', `${sha}..HEAD`], {
listeners: {
stdout: (data) => (output += data.toString())
}
});
output = (await exec_1.default('git', ['log', '--format=', '--no-renames', '--name-status', '-z', '-n', '1'])).stdout;
}
finally {
fixStdOutNullTermination();
@ -3835,23 +3828,52 @@ async function getChangesAgainstSha(sha) {
}
return parseGitDiffOutput(output);
}
exports.getChangesAgainstSha = getChangesAgainstSha;
async function getChangesSinceRef(ref, initialFetchDepth) {
// Fetch and add base branch
core.startGroup(`Fetching ${ref} from origin until merge-base is found`);
await exec_1.exec('git', ['fetch', `--depth=${initialFetchDepth}`, '--no-tags', 'origin', `${ref}:${ref}`]);
exports.getChangesInLastCommit = getChangesInLastCommit;
async function getChanges(ref) {
if (!(await hasCommit(ref))) {
// Fetch single commit
core.startGroup(`Fetching ${ref} from origin`);
await exec_1.default('git', ['fetch', '--depth=1', '--no-tags', '--no-auto-gc', 'origin', ref]);
core.endGroup();
}
// Get differences between ref and HEAD
core.startGroup(`Change detection ${ref}..HEAD`);
let output = '';
try {
// Two dots '..' change detection - directly compares two versions
output = (await exec_1.default('git', ['diff', '--no-renames', '--name-status', '-z', `${ref}..HEAD`])).stdout;
}
finally {
fixStdOutNullTermination();
core.endGroup();
}
return parseGitDiffOutput(output);
}
exports.getChanges = getChanges;
async function getChangesSinceMergeBase(ref, initialFetchDepth) {
if (!(await hasCommit(ref))) {
// Fetch and add base branch
core.startGroup(`Fetching ${ref}`);
try {
await exec_1.default('git', ['fetch', `--depth=${initialFetchDepth}`, '--no-tags', 'origin', `${ref}:${ref}`]);
}
finally {
core.endGroup();
}
}
async function hasMergeBase() {
return (await exec_1.exec('git', ['merge-base', ref, 'HEAD'], { ignoreReturnCode: true })) === 0;
return (await exec_1.default('git', ['merge-base', ref, 'HEAD'], { ignoreReturnCode: true })).code === 0;
}
async function countCommits() {
return (await getNumberOfCommits('HEAD')) + (await getNumberOfCommits(ref));
}
core.startGroup(`Searching for merge-base with ${ref}`);
// Fetch more commits until merge-base is found
if (!(await hasMergeBase())) {
let deepen = initialFetchDepth;
let lastCommitsCount = await countCommits();
do {
await exec_1.exec('git', ['fetch', `--deepen=${deepen}`, '--no-tags', '--no-auto-gc', '-q']);
await exec_1.default('git', ['fetch', `--deepen=${deepen}`, '--no-tags', '--no-auto-gc']);
const count = await countCommits();
if (count <= lastCommitsCount) {
core.info('No merge base found - all files will be listed as added');
@ -3868,11 +3890,7 @@ async function getChangesSinceRef(ref, initialFetchDepth) {
let output = '';
try {
// Three dots '...' change detection - finds merge-base and compares against it
await exec_1.exec('git', ['diff', '--no-renames', '--name-status', '-z', `${ref}...HEAD`], {
listeners: {
stdout: (data) => (output += data.toString())
}
});
output = (await exec_1.default('git', ['diff', '--no-renames', '--name-status', '-z', `${ref}...HEAD`])).stdout;
}
finally {
fixStdOutNullTermination();
@ -3880,7 +3898,7 @@ async function getChangesSinceRef(ref, initialFetchDepth) {
}
return parseGitDiffOutput(output);
}
exports.getChangesSinceRef = getChangesSinceRef;
exports.getChangesSinceMergeBase = getChangesSinceMergeBase;
function parseGitDiffOutput(output) {
const tokens = output.split('\u0000').filter(s => s.length > 0);
const files = [];
@ -3897,11 +3915,7 @@ async function listAllFilesAsAdded() {
core.startGroup('Listing all files tracked by git');
let output = '';
try {
await exec_1.exec('git', ['ls-files', '-z'], {
listeners: {
stdout: (data) => (output += data.toString())
}
});
output = (await exec_1.default('git', ['ls-files', '-z'])).stdout;
}
finally {
fixStdOutNullTermination();
@ -3916,32 +3930,50 @@ async function listAllFilesAsAdded() {
}));
}
exports.listAllFilesAsAdded = listAllFilesAsAdded;
function isTagRef(ref) {
return ref.startsWith('refs/tags/');
}
exports.isTagRef = isTagRef;
function trimRefs(ref) {
return trimStart(ref, 'refs/');
}
exports.trimRefs = trimRefs;
function trimRefsHeads(ref) {
const trimRef = trimStart(ref, 'refs/');
return trimStart(trimRef, 'heads/');
}
exports.trimRefsHeads = trimRefsHeads;
async function getNumberOfCommits(ref) {
let output = '';
await exec_1.exec('git', ['rev-list', `--count`, ref], {
listeners: {
stdout: (data) => (output += data.toString())
async function getCurrentRef() {
core.startGroup(`Determining current ref`);
try {
const branch = (await exec_1.default('git', ['branch', '--show-current'])).stdout.trim();
if (branch) {
return branch;
}
});
const describe = await exec_1.default('git', ['describe', '--tags', '--exact-match'], { ignoreReturnCode: true });
if (describe.code === 0) {
return describe.stdout.trim();
}
return (await exec_1.default('git', ['rev-parse', 'HEAD'])).stdout.trim();
}
finally {
core.endGroup();
}
}
exports.getCurrentRef = getCurrentRef;
function getShortName(ref) {
if (!ref)
return '';
const heads = 'refs/heads/';
const tags = 'refs/tags/';
if (ref.startsWith(heads))
return ref.slice(heads.length);
if (ref.startsWith(tags))
return ref.slice(tags.length);
return ref;
}
exports.getShortName = getShortName;
async function hasCommit(ref) {
core.startGroup(`Checking if commit for ${ref} is locally available`);
try {
return (await exec_1.default('git', ['cat-file', '-e', `${ref}^{commit}`], { ignoreReturnCode: true })).code === 0;
}
finally {
core.endGroup();
}
}
async function getNumberOfCommits(ref) {
const output = (await exec_1.default('git', ['rev-list', `--count`, ref])).stdout;
const count = parseInt(output);
return isNaN(count) ? 0 : count;
}
function trimStart(ref, start) {
return ref.startsWith(start) ? ref.substr(start.length) : ref;
}
function fixStdOutNullTermination() {
// Previous command uses NULL as delimiters and output is printed to stdout.
// We have to make sure next thing written to stdout will start on new line.
@ -4641,9 +4673,11 @@ function getConfigFileContent(configPath) {
async function getChangedFiles(token, base, initialFetchDepth) {
if (github.context.eventName === 'pull_request' || github.context.eventName === 'pull_request_target') {
const pr = github.context.payload.pull_request;
return token
? await getChangedFilesFromApi(token, pr)
: await git.getChangesSinceRef(pr.base.ref, initialFetchDepth);
if (token) {
return await getChangedFilesFromApi(token, pr);
}
core.info('Github token is not available - changes will be detected from PRs merge commit');
return await git.getChangesInLastCommit();
}
else if (github.context.eventName === 'push') {
return getChangedFilesFromPush(base, initialFetchDepth);
@ -4653,26 +4687,41 @@ async function getChangedFiles(token, base, initialFetchDepth) {
}
}
async function getChangedFilesFromPush(base, initialFetchDepth) {
var _a;
const push = github.context.payload;
// No change detection for pushed tags
if (git.isTagRef(push.ref)) {
core.info('Workflow is triggered by pushing of tag - all files will be listed as added');
return await git.listAllFilesAsAdded();
const defaultRef = (_a = push.repository) === null || _a === void 0 ? void 0 : _a.default_branch;
const pushRef = git.getShortName(push.ref) ||
(core.warning(`'ref' field is missing in PUSH event payload - using current branch, tag or commit SHA`),
await git.getCurrentRef());
const baseRef = git.getShortName(base) || defaultRef;
if (!baseRef) {
throw new Error("This action requires 'base' input to be configured or 'repository.default_branch' to be set in the event payload");
}
const baseRef = git.trimRefsHeads(base || push.repository.default_branch);
const pushRef = git.trimRefsHeads(push.ref);
// If base references same branch it was pushed to, we will do comparison against the previously pushed commit.
// If base references same branch it was pushed to,
// we will do comparison against the previously pushed commit
if (baseRef === pushRef) {
if (!push.before) {
core.warning(`'before' field is missing in PUSH event payload - changes will be detected from last commit`);
return await git.getChangesInLastCommit();
}
// If there is no previously pushed commit,
// we will do comparison against the default branch or return all as added
if (push.before === git.NULL_SHA) {
core.info('First push of a branch detected - all files will be listed as added');
return await git.listAllFilesAsAdded();
if (defaultRef && baseRef !== defaultRef) {
core.info(`First push of a branch detected - changes will be detected against the default branch ${defaultRef}`);
return await git.getChangesSinceMergeBase(defaultRef, initialFetchDepth);
}
else {
core.info('Initial push detected - all files will be listed as added');
return await git.listAllFilesAsAdded();
}
}
core.info(`Changes will be detected against the last previously pushed commit on same branch (${pushRef})`);
return await git.getChangesAgainstSha(push.before);
return await git.getChanges(push.before);
}
// Changes introduced by current branch against the base branch
core.info(`Changes will be detected against the branch ${baseRef}`);
return await git.getChangesSinceRef(baseRef, initialFetchDepth);
return await git.getChangesSinceMergeBase(baseRef, initialFetchDepth);
}
// Uses github REST api to get list of files changed in PR
async function getChangedFilesFromApi(token, pullRequest) {
@ -15612,6 +15661,31 @@ exports.getUserAgent = getUserAgent;
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 807:
/***/ (function(__unusedmodule, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const exec_1 = __webpack_require__(986);
// Wraps original exec() function
// Returns exit code and whole stdout/stderr
async function exec(commandLine, args, options) {
options = options || {};
let stdout = '';
let stderr = '';
options.listeners = {
stdout: (data) => (stdout += data.toString()),
stderr: (data) => (stderr += data.toString())
};
const code = await exec_1.exec(commandLine, args, options);
return { code, stdout, stderr };
}
exports.default = exec;
/***/ }),
/***/ 809:

21
src/exec.ts Normal file
View File

@ -0,0 +1,21 @@
import {exec as execImpl, ExecOptions} from '@actions/exec'
// Wraps original exec() function
// Returns exit code and whole stdout/stderr
export default async function exec(commandLine: string, args?: string[], options?: ExecOptions): Promise<ExecResult> {
options = options || {}
let stdout = ''
let stderr = ''
options.listeners = {
stdout: (data: Buffer) => (stdout += data.toString()),
stderr: (data: Buffer) => (stderr += data.toString())
}
const code = await execImpl(commandLine, args, options)
return {code, stdout, stderr}
}
export interface ExecResult {
code: number
stdout: string
stderr: string
}

View File

@ -1,25 +1,14 @@
import {exec} from '@actions/exec'
import exec from './exec'
import * as core from '@actions/core'
import {File, ChangeStatus} from './file'
export const NULL_SHA = '0000000000000000000000000000000000000000'
export async function getChangesAgainstSha(sha: string): Promise<File[]> {
// Fetch single commit
core.startGroup(`Fetching ${sha} from origin`)
await exec('git', ['fetch', '--depth=1', '--no-tags', 'origin', sha])
core.endGroup()
// Get differences between sha and HEAD
core.startGroup(`Change detection ${sha}..HEAD`)
export async function getChangesInLastCommit(): Promise<File[]> {
core.startGroup(`Change detection in last commit`)
let output = ''
try {
// Two dots '..' change detection - directly compares two versions
await exec('git', ['diff', '--no-renames', '--name-status', '-z', `${sha}..HEAD`], {
listeners: {
stdout: (data: Buffer) => (output += data.toString())
}
})
output = (await exec('git', ['log', '--format=', '--no-renames', '--name-status', '-z', '-n', '1'])).stdout
} finally {
fixStdOutNullTermination()
core.endGroup()
@ -28,25 +17,54 @@ export async function getChangesAgainstSha(sha: string): Promise<File[]> {
return parseGitDiffOutput(output)
}
export async function getChangesSinceRef(ref: string, initialFetchDepth: number): Promise<File[]> {
// Fetch and add base branch
core.startGroup(`Fetching ${ref} from origin until merge-base is found`)
await exec('git', ['fetch', `--depth=${initialFetchDepth}`, '--no-tags', 'origin', `${ref}:${ref}`])
export async function getChanges(ref: string): Promise<File[]> {
if (!(await hasCommit(ref))) {
// Fetch single commit
core.startGroup(`Fetching ${ref} from origin`)
await exec('git', ['fetch', '--depth=1', '--no-tags', '--no-auto-gc', 'origin', ref])
core.endGroup()
}
// Get differences between ref and HEAD
core.startGroup(`Change detection ${ref}..HEAD`)
let output = ''
try {
// Two dots '..' change detection - directly compares two versions
output = (await exec('git', ['diff', '--no-renames', '--name-status', '-z', `${ref}..HEAD`])).stdout
} finally {
fixStdOutNullTermination()
core.endGroup()
}
return parseGitDiffOutput(output)
}
export async function getChangesSinceMergeBase(ref: string, initialFetchDepth: number): Promise<File[]> {
if (!(await hasCommit(ref))) {
// Fetch and add base branch
core.startGroup(`Fetching ${ref}`)
try {
await exec('git', ['fetch', `--depth=${initialFetchDepth}`, '--no-tags', 'origin', `${ref}:${ref}`])
} finally {
core.endGroup()
}
}
async function hasMergeBase(): Promise<boolean> {
return (await exec('git', ['merge-base', ref, 'HEAD'], {ignoreReturnCode: true})) === 0
return (await exec('git', ['merge-base', ref, 'HEAD'], {ignoreReturnCode: true})).code === 0
}
async function countCommits(): Promise<number> {
return (await getNumberOfCommits('HEAD')) + (await getNumberOfCommits(ref))
}
core.startGroup(`Searching for merge-base with ${ref}`)
// Fetch more commits until merge-base is found
if (!(await hasMergeBase())) {
let deepen = initialFetchDepth
let lastCommitsCount = await countCommits()
do {
await exec('git', ['fetch', `--deepen=${deepen}`, '--no-tags', '--no-auto-gc', '-q'])
await exec('git', ['fetch', `--deepen=${deepen}`, '--no-tags', '--no-auto-gc'])
const count = await countCommits()
if (count <= lastCommitsCount) {
core.info('No merge base found - all files will be listed as added')
@ -64,11 +82,7 @@ export async function getChangesSinceRef(ref: string, initialFetchDepth: number)
let output = ''
try {
// Three dots '...' change detection - finds merge-base and compares against it
await exec('git', ['diff', '--no-renames', '--name-status', '-z', `${ref}...HEAD`], {
listeners: {
stdout: (data: Buffer) => (output += data.toString())
}
})
output = (await exec('git', ['diff', '--no-renames', '--name-status', '-z', `${ref}...HEAD`])).stdout
} finally {
fixStdOutNullTermination()
core.endGroup()
@ -93,11 +107,7 @@ export async function listAllFilesAsAdded(): Promise<File[]> {
core.startGroup('Listing all files tracked by git')
let output = ''
try {
await exec('git', ['ls-files', '-z'], {
listeners: {
stdout: (data: Buffer) => (output += data.toString())
}
})
output = (await exec('git', ['ls-files', '-z'])).stdout
} finally {
fixStdOutNullTermination()
core.endGroup()
@ -112,34 +122,52 @@ export async function listAllFilesAsAdded(): Promise<File[]> {
}))
}
export function isTagRef(ref: string): boolean {
return ref.startsWith('refs/tags/')
export async function getCurrentRef(): Promise<string> {
core.startGroup(`Determining current ref`)
try {
const branch = (await exec('git', ['branch', '--show-current'])).stdout.trim()
if (branch) {
return branch
}
const describe = await exec('git', ['describe', '--tags', '--exact-match'], {ignoreReturnCode: true})
if (describe.code === 0) {
return describe.stdout.trim()
}
return (await exec('git', ['rev-parse', 'HEAD'])).stdout.trim()
} finally {
core.endGroup()
}
}
export function trimRefs(ref: string): string {
return trimStart(ref, 'refs/')
export function getShortName(ref: string): string {
if (!ref) return ''
const heads = 'refs/heads/'
const tags = 'refs/tags/'
if (ref.startsWith(heads)) return ref.slice(heads.length)
if (ref.startsWith(tags)) return ref.slice(tags.length)
return ref
}
export function trimRefsHeads(ref: string): string {
const trimRef = trimStart(ref, 'refs/')
return trimStart(trimRef, 'heads/')
async function hasCommit(ref: string): Promise<boolean> {
core.startGroup(`Checking if commit for ${ref} is locally available`)
try {
return (await exec('git', ['cat-file', '-e', `${ref}^{commit}`], {ignoreReturnCode: true})).code === 0
} finally {
core.endGroup()
}
}
async function getNumberOfCommits(ref: string): Promise<number> {
let output = ''
await exec('git', ['rev-list', `--count`, ref], {
listeners: {
stdout: (data: Buffer) => (output += data.toString())
}
})
const output = (await exec('git', ['rev-list', `--count`, ref])).stdout
const count = parseInt(output)
return isNaN(count) ? 0 : count
}
function trimStart(ref: string, start: string): string {
return ref.startsWith(start) ? ref.substr(start.length) : ref
}
function fixStdOutNullTermination(): void {
// Previous command uses NULL as delimiters and output is printed to stdout.
// We have to make sure next thing written to stdout will start on new line.

View File

@ -57,9 +57,11 @@ function getConfigFileContent(configPath: string): string {
async function getChangedFiles(token: string, base: string, initialFetchDepth: number): Promise<File[]> {
if (github.context.eventName === 'pull_request' || github.context.eventName === 'pull_request_target') {
const pr = github.context.payload.pull_request as Webhooks.WebhookPayloadPullRequestPullRequest
return token
? await getChangedFilesFromApi(token, pr)
: await git.getChangesSinceRef(pr.base.ref, initialFetchDepth)
if (token) {
return await getChangedFilesFromApi(token, pr)
}
core.info('Github token is not available - changes will be detected from PRs merge commit')
return await git.getChangesInLastCommit()
} else if (github.context.eventName === 'push') {
return getChangedFilesFromPush(base, initialFetchDepth)
} else {
@ -69,30 +71,47 @@ async function getChangedFiles(token: string, base: string, initialFetchDepth: n
async function getChangedFilesFromPush(base: string, initialFetchDepth: number): Promise<File[]> {
const push = github.context.payload as Webhooks.WebhookPayloadPush
const defaultRef = push.repository?.default_branch
// No change detection for pushed tags
if (git.isTagRef(push.ref)) {
core.info('Workflow is triggered by pushing of tag - all files will be listed as added')
return await git.listAllFilesAsAdded()
const pushRef =
git.getShortName(push.ref) ||
(core.warning(`'ref' field is missing in PUSH event payload - using current branch, tag or commit SHA`),
await git.getCurrentRef())
const baseRef = git.getShortName(base) || defaultRef
if (!baseRef) {
throw new Error(
"This action requires 'base' input to be configured or 'repository.default_branch' to be set in the event payload"
)
}
const baseRef = git.trimRefsHeads(base || push.repository.default_branch)
const pushRef = git.trimRefsHeads(push.ref)
// If base references same branch it was pushed to, we will do comparison against the previously pushed commit.
// If base references same branch it was pushed to,
// we will do comparison against the previously pushed commit
if (baseRef === pushRef) {
if (!push.before) {
core.warning(`'before' field is missing in PUSH event payload - changes will be detected from last commit`)
return await git.getChangesInLastCommit()
}
// If there is no previously pushed commit,
// we will do comparison against the default branch or return all as added
if (push.before === git.NULL_SHA) {
core.info('First push of a branch detected - all files will be listed as added')
return await git.listAllFilesAsAdded()
if (defaultRef && baseRef !== defaultRef) {
core.info(`First push of a branch detected - changes will be detected against the default branch ${defaultRef}`)
return await git.getChangesSinceMergeBase(defaultRef, initialFetchDepth)
} else {
core.info('Initial push detected - all files will be listed as added')
return await git.listAllFilesAsAdded()
}
}
core.info(`Changes will be detected against the last previously pushed commit on same branch (${pushRef})`)
return await git.getChangesAgainstSha(push.before)
return await git.getChanges(push.before)
}
// Changes introduced by current branch against the base branch
core.info(`Changes will be detected against the branch ${baseRef}`)
return await git.getChangesSinceRef(baseRef, initialFetchDepth)
return await git.getChangesSinceMergeBase(baseRef, initialFetchDepth)
}
// Uses github REST api to get list of files changed in PR