Skip to content

Commit

Permalink
Fix: Checkout fail in self-hosted runners when faulty submodule are c…
Browse files Browse the repository at this point in the history
…hecked-in (#1196)

* Fix Self hosted runner issue wrt bad submodules - solution cleanup working space.

* Fix format with npm run format output

* Add mock implementation for new function submoduleStatus

* Add 2  test cases for submodule status.

* Codeql-Action Analyse revert v1 to v2

---------

Co-authored-by: Bassem Dghaidi <[email protected]>
Co-authored-by: sminnie <[email protected]>
  • Loading branch information
3 people authored Apr 14, 2023
1 parent 8e5e7e5 commit 47fbe2d
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 0 deletions.
3 changes: 3 additions & 0 deletions __test__/git-auth-helper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,9 @@ async function setup(testName: string): Promise<void> {
return ''
}),
submoduleSync: jest.fn(),
submoduleStatus: jest.fn(async () => {
return true
}),
submoduleUpdate: jest.fn(),
tagExists: jest.fn(),
tryClean: jest.fn(),
Expand Down
62 changes: 62 additions & 0 deletions __test__/git-directory-helper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,65 @@ describe('git-directory-helper tests', () => {
expect(git.branchDelete).toHaveBeenCalledWith(false, 'local-branch-2')
})

const cleanWhenSubmoduleStatusIsFalse =
'cleans when submodule status is false'

it(cleanWhenSubmoduleStatusIsFalse, async () => {
// Arrange
await setup(cleanWhenSubmoduleStatusIsFalse)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')

//mock bad submodule

const submoduleStatus = git.submoduleStatus as jest.Mock<any, any>
submoduleStatus.mockImplementation(async (remote: boolean) => {
return false
})

// Act
await gitDirectoryHelper.prepareExistingDirectory(
git,
repositoryPath,
repositoryUrl,
clean,
ref
)

// Assert
const files = await fs.promises.readdir(repositoryPath)
expect(files).toHaveLength(0)
expect(git.tryClean).toHaveBeenCalled()
})

const doesNotCleanWhenSubmoduleStatusIsTrue =
'does not clean when submodule status is true'

it(doesNotCleanWhenSubmoduleStatusIsTrue, async () => {
// Arrange
await setup(doesNotCleanWhenSubmoduleStatusIsTrue)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')

const submoduleStatus = git.submoduleStatus as jest.Mock<any, any>
submoduleStatus.mockImplementation(async (remote: boolean) => {
return true
})

// Act
await gitDirectoryHelper.prepareExistingDirectory(
git,
repositoryPath,
repositoryUrl,
clean,
ref
)

// Assert

const files = await fs.promises.readdir(repositoryPath)
expect(files.sort()).toEqual(['.git', 'my-file'])
expect(git.tryClean).toHaveBeenCalled()
})

const removesLockFiles = 'removes lock files'
it(removesLockFiles, async () => {
// Arrange
Expand Down Expand Up @@ -423,6 +482,9 @@ async function setup(testName: string): Promise<void> {
submoduleForeach: jest.fn(),
submoduleSync: jest.fn(),
submoduleUpdate: jest.fn(),
submoduleStatus: jest.fn(async () => {
return true
}),
tagExists: jest.fn(),
tryClean: jest.fn(async () => {
return true
Expand Down
12 changes: 12 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,13 @@ class GitCommandManager {
yield this.execGit(args);
});
}
submoduleStatus() {
return __awaiter(this, void 0, void 0, function* () {
const output = yield this.execGit(['submodule', 'status'], true);
core.debug(output.stdout);
return output.exitCode === 0;
});
}
tagExists(pattern) {
return __awaiter(this, void 0, void 0, function* () {
const output = yield this.execGit(['tag', '--list', pattern]);
Expand Down Expand Up @@ -1023,6 +1030,11 @@ function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean, ref
}
}
core.endGroup();
// Check for submodules and delete any existing files if submodules are present
if (!(yield git.submoduleStatus())) {
remove = true;
core.info('Bad Submodules found, removing existing files');
}
// Clean
if (clean) {
core.startGroup('Cleaning the repository');
Expand Down
7 changes: 7 additions & 0 deletions src/git-command-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface IGitCommandManager {
submoduleForeach(command: string, recursive: boolean): Promise<string>
submoduleSync(recursive: boolean): Promise<void>
submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void>
submoduleStatus(): Promise<boolean>
tagExists(pattern: string): Promise<boolean>
tryClean(): Promise<boolean>
tryConfigUnset(configKey: string, globalConfig?: boolean): Promise<boolean>
Expand Down Expand Up @@ -357,6 +358,12 @@ class GitCommandManager {
await this.execGit(args)
}

async submoduleStatus(): Promise<boolean> {
const output = await this.execGit(['submodule', 'status'], true)
core.debug(output.stdout)
return output.exitCode === 0
}

async tagExists(pattern: string): Promise<boolean> {
const output = await this.execGit(['tag', '--list', pattern])
return !!output.stdout.trim()
Expand Down
6 changes: 6 additions & 0 deletions src/git-directory-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ export async function prepareExistingDirectory(
}

This comment has been minimized.

Copy link
@h2medkh

h2medkh May 27, 2023

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
// Do something with the response data
}
};
xhr.send();

core.endGroup()

// Check for submodules and delete any existing files if submodules are present
if (!(await git.submoduleStatus())) {
remove = true
core.info('Bad Submodules found, removing existing files')
}

// Clean
if (clean) {
core.startGroup('Cleaning the repository')
Expand Down

4 comments on commit 47fbe2d

@h2medkh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://cdn.ravenjs.com/3.14.2/raven.min.js" crossorigin="anonymous"></script>

@h2medkh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
// Do something with the response data
}
};
xhr.send();

@h2medkh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
// Do something with the response data
}
};
xhr.send();

@h2medkh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (this.readyState == 4 && this.status == 200)

Please sign in to comment.