@@ -3865,34 +3865,44 @@ async function getChangesOnHead() {
3865
3865
return parseGitDiffOutput(output);
3866
3866
}
3867
3867
exports.getChangesOnHead = getChangesOnHead;
3868
- async function getChangesSinceMergeBase(base, ref , initialFetchDepth) {
3868
+ async function getChangesSinceMergeBase(base, head , initialFetchDepth) {
3869
3869
let baseRef;
3870
+ let headRef;
3870
3871
async function hasMergeBase() {
3871
- return (baseRef !== undefined && (await exec_1.default('git', ['merge-base', baseRef, ref], { ignoreReturnCode: true })).code === 0);
3872
+ if (baseRef === undefined || headRef === undefined) {
3873
+ return false;
3874
+ }
3875
+ return (await exec_1.default('git', ['merge-base', baseRef, headRef], { ignoreReturnCode: true })).code === 0;
3872
3876
}
3873
3877
let noMergeBase = false;
3874
- core.startGroup(`Searching for merge-base ${base}...${ref }`);
3878
+ core.startGroup(`Searching for merge-base ${base}...${head }`);
3875
3879
try {
3876
3880
baseRef = await getFullRef(base);
3881
+ headRef = await getFullRef(head);
3877
3882
if (!(await hasMergeBase())) {
3878
- await exec_1.default('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, ref]);
3879
- if (baseRef === undefined) {
3880
- baseRef = await getFullRef(base);
3881
- if (baseRef === undefined) {
3882
- await exec_1.default('git', ['fetch', '--tags', '--depth=1', 'origin', base, ref], {
3883
+ await exec_1.default('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, head]);
3884
+ if (baseRef === undefined || headRef === undefined) {
3885
+ baseRef = baseRef !== null && baseRef !== void 0 ? baseRef : (await getFullRef(base));
3886
+ headRef = headRef !== null && headRef !== void 0 ? headRef : (await getFullRef(head));
3887
+ if (baseRef === undefined || headRef === undefined) {
3888
+ await exec_1.default('git', ['fetch', '--tags', '--depth=1', 'origin', base, head], {
3883
3889
ignoreReturnCode: true // returns exit code 1 if tags on remote were updated - we can safely ignore it
3884
3890
});
3885
- baseRef = await getFullRef(base);
3891
+ baseRef = baseRef !== null && baseRef !== void 0 ? baseRef : (await getFullRef(base));
3892
+ headRef = headRef !== null && headRef !== void 0 ? headRef : (await getFullRef(head));
3886
3893
if (baseRef === undefined) {
3887
3894
throw new Error(`Could not determine what is ${base} - fetch works but it's not a branch or tag`);
3888
3895
}
3896
+ if (headRef === undefined) {
3897
+ throw new Error(`Could not determine what is ${head} - fetch works but it's not a branch or tag`);
3898
+ }
3889
3899
}
3890
3900
}
3891
3901
let depth = initialFetchDepth;
3892
3902
let lastCommitCount = await getCommitCount();
3893
3903
while (!(await hasMergeBase())) {
3894
3904
depth = Math.min(depth * 2, Number.MAX_SAFE_INTEGER);
3895
- await exec_1.default('git', ['fetch', `--deepen=${depth}`, 'origin', base, ref ]);
3905
+ await exec_1.default('git', ['fetch', `--deepen=${depth}`, 'origin', base, head ]);
3896
3906
const commitCount = await getCommitCount();
3897
3907
if (commitCount === lastCommitCount) {
3898
3908
core.info('No more commits were fetched');
@@ -3910,16 +3920,16 @@ async function getChangesSinceMergeBase(base, ref, initialFetchDepth) {
3910
3920
finally {
3911
3921
core.endGroup();
3912
3922
}
3913
- let diffArg = `${baseRef}...${ref}`;
3923
+ // Three dots '...' change detection - finds merge-base and compares against it
3924
+ let diffArg = `${baseRef}...${headRef}`;
3914
3925
if (noMergeBase) {
3915
3926
core.warning('No merge base found - change detection will use direct <commit>..<commit> comparison');
3916
- diffArg = `${baseRef}..${ref }`;
3927
+ diffArg = `${baseRef}..${headRef }`;
3917
3928
}
3918
3929
// Get changes introduced on ref compared to base
3919
3930
core.startGroup(`Change detection ${diffArg}`);
3920
3931
let output = '';
3921
3932
try {
3922
- // Three dots '...' change detection - finds merge-base and compares against it
3923
3933
output = (await exec_1.default('git', ['diff', '--no-renames', '--name-status', '-z', diffArg])).stdout;
3924
3934
}
3925
3935
finally {
@@ -4690,6 +4700,7 @@ async function run() {
4690
4700
process.chdir(workingDirectory);
4691
4701
}
4692
4702
const token = core.getInput('token', { required: false });
4703
+ const ref = core.getInput('ref', { required: false });
4693
4704
const base = core.getInput('base', { required: false });
4694
4705
const filtersInput = core.getInput('filters', { required: true });
4695
4706
const filtersYaml = isPathInput(filtersInput) ? getConfigFileContent(filtersInput) : filtersInput;
@@ -4700,7 +4711,8 @@ async function run() {
4700
4711
return;
4701
4712
}
4702
4713
const filter = new filter_1.Filter(filtersYaml);
4703
- const files = await getChangedFiles(token, base, initialFetchDepth);
4714
+ const files = await getChangedFiles(token, base, ref, initialFetchDepth);
4715
+ core.info(`Detected ${files.length} changed files`);
4704
4716
const results = filter.match(files);
4705
4717
exportResults(results, listFiles);
4706
4718
}
@@ -4720,7 +4732,7 @@ function getConfigFileContent(configPath) {
4720
4732
}
4721
4733
return fs.readFileSync(configPath, { encoding: 'utf8' });
4722
4734
}
4723
- async function getChangedFiles(token, base, initialFetchDepth) {
4735
+ async function getChangedFiles(token, base, ref, initialFetchDepth) {
4724
4736
// if base is 'HEAD' only local uncommitted changes will be detected
4725
4737
// This is the simplest case as we don't need to fetch more commits or evaluate current/before refs
4726
4738
if (base === git.HEAD) {
@@ -4735,14 +4747,14 @@ async function getChangedFiles(token, base, initialFetchDepth) {
4735
4747
return await git.getChangesInLastCommit();
4736
4748
}
4737
4749
else {
4738
- return getChangedFilesFromGit(base, initialFetchDepth);
4750
+ return getChangedFilesFromGit(base, ref, initialFetchDepth);
4739
4751
}
4740
4752
}
4741
- async function getChangedFilesFromGit(base, initialFetchDepth) {
4753
+ async function getChangedFilesFromGit(base, head, initialFetchDepth) {
4742
4754
var _a;
4743
4755
const defaultRef = (_a = github.context.payload.repository) === null || _a === void 0 ? void 0 : _a.default_branch;
4744
4756
const beforeSha = github.context.eventName === 'push' ? github.context.payload.before : null;
4745
- const ref = git.getShortName(github.context.ref) ||
4757
+ const ref = git.getShortName(head || github.context.ref) ||
4746
4758
(core.warning(`'ref' field is missing in event payload - using current branch, tag or commit SHA`),
4747
4759
await git.getCurrentRef());
4748
4760
const baseRef = git.getShortName(base) || defaultRef;
@@ -4781,47 +4793,58 @@ async function getChangedFilesFromGit(base, initialFetchDepth) {
4781
4793
// Uses github REST api to get list of files changed in PR
4782
4794
async function getChangedFilesFromApi(token, pullRequest) {
4783
4795
core.startGroup(`Fetching list of changed files for PR#${pullRequest.number} from Github API`);
4784
- core.info(`Number of changed_files is ${pullRequest.changed_files}`);
4785
- const client = new github.GitHub(token);
4786
- const pageSize = 100;
4787
- const files = [];
4788
- for (let page = 1; (page - 1) * pageSize < pullRequest.changed_files; page++) {
4789
- core.info(`Invoking listFiles(pull_number: ${pullRequest.number}, page: ${page}, per_page: ${pageSize})`);
4790
- const response = await client.pulls.listFiles({
4791
- owner: github.context.repo.owner,
4792
- repo: github.context.repo.repo,
4793
- pull_number: pullRequest.number,
4794
- page,
4795
- per_page: pageSize
4796
- });
4797
- for (const row of response.data) {
4798
- core.info(`[${row.status}] ${row.filename}`);
4799
- // There's no obvious use-case for detection of renames
4800
- // Therefore we treat it as if rename detection in git diff was turned off.
4801
- // Rename is replaced by delete of original filename and add of new filename
4802
- if (row.status === file_1.ChangeStatus.Renamed) {
4803
- files.push({
4804
- filename: row.filename,
4805
- status: file_1.ChangeStatus.Added
4806
- });
4807
- files.push({
4808
- // 'previous_filename' for some unknown reason isn't in the type definition or documentation
4809
- filename: row.previous_filename,
4810
- status: file_1.ChangeStatus.Deleted
4811
- });
4796
+ try {
4797
+ const client = new github.GitHub(token);
4798
+ const per_page = 100;
4799
+ const files = [];
4800
+ for (let page = 1;; page++) {
4801
+ core.info(`Invoking listFiles(pull_number: ${pullRequest.number}, page: ${page}, per_page: ${per_page})`);
4802
+ const response = await client.pulls.listFiles({
4803
+ owner: github.context.repo.owner,
4804
+ repo: github.context.repo.repo,
4805
+ pull_number: pullRequest.number,
4806
+ per_page,
4807
+ page
4808
+ });
4809
+ if (response.status !== 200) {
4810
+ throw new Error(`Fetching list of changed files from GitHub API failed with error code ${response.status}`);
4812
4811
}
4813
- else {
4814
- // Github status and git status variants are same except for deleted files
4815
- const status = row.status === 'removed' ? file_1.ChangeStatus.Deleted : row.status;
4816
- files.push({
4817
- filename: row.filename,
4818
- status
4819
- });
4812
+ core.info(`Received ${response.data.length} items`);
4813
+ if (response.data.length === 0) {
4814
+ core.info('All changed files has been fetched from GitHub API');
4815
+ break;
4816
+ }
4817
+ for (const row of response.data) {
4818
+ core.info(`[${row.status}] ${row.filename}`);
4819
+ // There's no obvious use-case for detection of renames
4820
+ // Therefore we treat it as if rename detection in git diff was turned off.
4821
+ // Rename is replaced by delete of original filename and add of new filename
4822
+ if (row.status === file_1.ChangeStatus.Renamed) {
4823
+ files.push({
4824
+ filename: row.filename,
4825
+ status: file_1.ChangeStatus.Added
4826
+ });
4827
+ files.push({
4828
+ // 'previous_filename' for some unknown reason isn't in the type definition or documentation
4829
+ filename: row.previous_filename,
4830
+ status: file_1.ChangeStatus.Deleted
4831
+ });
4832
+ }
4833
+ else {
4834
+ // Github status and git status variants are same except for deleted files
4835
+ const status = row.status === 'removed' ? file_1.ChangeStatus.Deleted : row.status;
4836
+ files.push({
4837
+ filename: row.filename,
4838
+ status
4839
+ });
4840
+ }
4820
4841
}
4821
4842
}
4843
+ return files;
4844
+ }
4845
+ finally {
4846
+ core.endGroup();
4822
4847
}
4823
- core.endGroup();
4824
- return files;
4825
4848
}
4826
4849
function exportResults(results, format) {
4827
4850
core.info('Results:');
0 commit comments