Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check git version before attempting to disable sparse-checkout #1656

Merged
merged 5 commits into from Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion __test__/git-auth-helper.test.ts
Expand Up @@ -796,7 +796,8 @@ async function setup(testName: string): Promise<void> {
),
tryDisableAutomaticGarbageCollection: jest.fn(),
tryGetFetchUrl: jest.fn(),
tryReset: jest.fn()
tryReset: jest.fn(),
version: jest.fn()
}

settings = {
Expand Down
3 changes: 2 additions & 1 deletion __test__/git-directory-helper.test.ts
Expand Up @@ -501,6 +501,7 @@ async function setup(testName: string): Promise<void> {
}),
tryReset: jest.fn(async () => {
return true
})
}),
version: jest.fn()
}
}
28 changes: 27 additions & 1 deletion __test__/git-version.test.ts
@@ -1,4 +1,6 @@
import {GitVersion} from '../lib/git-version'
import { GitVersion } from '../src/git-version'
import {MinimumGitSparseCheckoutVersion} from '../src/git-command-manager'


describe('git-version tests', () => {
it('basics', async () => {
Expand Down Expand Up @@ -42,4 +44,28 @@ describe('git-version tests', () => {
expect(version.checkMinimum(new GitVersion('5.1'))).toBeFalsy()
expect(version.checkMinimum(new GitVersion('5.1.2'))).toBeFalsy()
})

it('sparse checkout', async () => {
expect(new GitVersion('1.0').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeFalsy()
expect(new GitVersion('1.99').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeFalsy()
expect(new GitVersion('2.24').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeFalsy()
expect(new GitVersion('2.24.0').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeFalsy()
expect(new GitVersion('2.24.1').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeFalsy()
expect(new GitVersion('2.24.9').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeFalsy()
expect(new GitVersion('2.25').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('2.25.0').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('2.25.1').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('2.25.9').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('2.26').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('2.26.0').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('2.26.1').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('2.26.9').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('2.99').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('3.0').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('3.99').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('4.0').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('4.99').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('5.0').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
expect(new GitVersion('5.99').checkMinimum(MinimumGitSparseCheckoutVersion)).toBeTruthy()
})
})
35 changes: 23 additions & 12 deletions dist/index.js
Expand Up @@ -467,7 +467,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createCommandManager = exports.MinimumGitVersion = void 0;
exports.createCommandManager = exports.MinimumGitSparseCheckoutVersion = exports.MinimumGitVersion = void 0;
const core = __importStar(__nccwpck_require__(2186));
const exec = __importStar(__nccwpck_require__(1514));
const fs = __importStar(__nccwpck_require__(7147));
Expand All @@ -480,7 +480,9 @@ const retryHelper = __importStar(__nccwpck_require__(2155));
const git_version_1 = __nccwpck_require__(3142);
// Auth header not supported before 2.9
// Wire protocol v2 not supported before 2.18
// sparse-checkout not supported before 2.25
exports.MinimumGitVersion = new git_version_1.GitVersion('2.18');
exports.MinimumGitSparseCheckoutVersion = new git_version_1.GitVersion('2.25');
function createCommandManager(workingDirectory, lfs, doSparseCheckout) {
return __awaiter(this, void 0, void 0, function* () {
return yield GitCommandManager.createCommandManager(workingDirectory, lfs, doSparseCheckout);
Expand All @@ -498,6 +500,7 @@ class GitCommandManager {
this.lfs = false;
this.doSparseCheckout = false;
this.workingDirectory = '';
this.gitVersion = new git_version_1.GitVersion();
}
branchDelete(remote, branch) {
return __awaiter(this, void 0, void 0, function* () {
Expand Down Expand Up @@ -850,6 +853,11 @@ class GitCommandManager {
return output.exitCode === 0;
});
}
version() {
return __awaiter(this, void 0, void 0, function* () {
return this.gitVersion;
});
}
static createCommandManager(workingDirectory, lfs, doSparseCheckout) {
return __awaiter(this, void 0, void 0, function* () {
const result = new GitCommandManager();
Expand Down Expand Up @@ -901,21 +909,21 @@ class GitCommandManager {
this.gitPath = yield io.which('git', true);
// Git version
core.debug('Getting git version');
let gitVersion = new git_version_1.GitVersion();
this.gitVersion = new git_version_1.GitVersion();
let gitOutput = yield this.execGit(['version']);
let stdout = gitOutput.stdout.trim();
if (!stdout.includes('\n')) {
const match = stdout.match(/\d+\.\d+(\.\d+)?/);
if (match) {
gitVersion = new git_version_1.GitVersion(match[0]);
this.gitVersion = new git_version_1.GitVersion(match[0]);
}
}
if (!gitVersion.isValid()) {
if (!this.gitVersion.isValid()) {
throw new Error('Unable to determine git version');
}
// Minimum git version
if (!gitVersion.checkMinimum(exports.MinimumGitVersion)) {
throw new Error(`Minimum required git version is ${exports.MinimumGitVersion}. Your git ('${this.gitPath}') is ${gitVersion}`);
if (!this.gitVersion.checkMinimum(exports.MinimumGitVersion)) {
throw new Error(`Minimum required git version is ${exports.MinimumGitVersion}. Your git ('${this.gitPath}') is ${this.gitVersion}`);
}
if (this.lfs) {
// Git-lfs version
Expand Down Expand Up @@ -943,14 +951,12 @@ class GitCommandManager {
}
this.doSparseCheckout = doSparseCheckout;
if (this.doSparseCheckout) {
// The `git sparse-checkout` command was introduced in Git v2.25.0
const minimumGitSparseCheckoutVersion = new git_version_1.GitVersion('2.25');
if (!gitVersion.checkMinimum(minimumGitSparseCheckoutVersion)) {
throw new Error(`Minimum Git version required for sparse checkout is ${minimumGitSparseCheckoutVersion}. Your git ('${this.gitPath}') is ${gitVersion}`);
if (!this.gitVersion.checkMinimum(exports.MinimumGitSparseCheckoutVersion)) {
throw new Error(`Minimum Git version required for sparse checkout is ${exports.MinimumGitSparseCheckoutVersion}. Your git ('${this.gitPath}') is ${this.gitVersion}`);
}
}
// Set the user agent
const gitHttpUserAgent = `git/${gitVersion} (github-actions-checkout)`;
const gitHttpUserAgent = `git/${this.gitVersion} (github-actions-checkout)`;
core.debug(`Set git useragent to: ${gitHttpUserAgent}`);
this.gitEnv['GIT_HTTP_USER_AGENT'] = gitHttpUserAgent;
});
Expand Down Expand Up @@ -1155,6 +1161,7 @@ const path = __importStar(__nccwpck_require__(1017));
const refHelper = __importStar(__nccwpck_require__(8601));
const stateHelper = __importStar(__nccwpck_require__(8647));
const urlHelper = __importStar(__nccwpck_require__(9437));
const git_command_manager_1 = __nccwpck_require__(738);
function getSource(settings) {
return __awaiter(this, void 0, void 0, function* () {
// Repository URL
Expand Down Expand Up @@ -1288,7 +1295,11 @@ function getSource(settings) {
}
// Sparse checkout
if (!settings.sparseCheckout) {
yield git.disableSparseCheckout();
let gitVersion = yield git.version();
// no need to disable sparse-checkout if the installed git runtime doesn't even support it.
if (gitVersion.checkMinimum(git_command_manager_1.MinimumGitSparseCheckoutVersion)) {
yield git.disableSparseCheckout();
}
}
else {
core.startGroup('Setting up sparse checkout');
Expand Down
26 changes: 16 additions & 10 deletions src/git-command-manager.ts
Expand Up @@ -11,7 +11,9 @@ import {GitVersion} from './git-version'

// Auth header not supported before 2.9
// Wire protocol v2 not supported before 2.18
// sparse-checkout not supported before 2.25
export const MinimumGitVersion = new GitVersion('2.18')
export const MinimumGitSparseCheckoutVersion = new GitVersion('2.25');
jww3 marked this conversation as resolved.
Show resolved Hide resolved

export interface IGitCommandManager {
branchDelete(remote: boolean, branch: string): Promise<void>
Expand Down Expand Up @@ -60,6 +62,7 @@ export interface IGitCommandManager {
tryDisableAutomaticGarbageCollection(): Promise<boolean>
tryGetFetchUrl(): Promise<string>
tryReset(): Promise<boolean>
version(): Promise<GitVersion>
}

export async function createCommandManager(
Expand All @@ -83,6 +86,7 @@ class GitCommandManager {
private lfs = false
private doSparseCheckout = false
private workingDirectory = ''
private gitVersion: GitVersion = new GitVersion()

// Private constructor; use createCommandManager()
private constructor() {}
Expand Down Expand Up @@ -480,6 +484,10 @@ class GitCommandManager {
return output.exitCode === 0
}

async version(): Promise<GitVersion> {
return this.gitVersion
}

static async createCommandManager(
workingDirectory: string,
lfs: boolean,
Expand Down Expand Up @@ -556,23 +564,23 @@ class GitCommandManager {

// Git version
core.debug('Getting git version')
let gitVersion = new GitVersion()
this.gitVersion = new GitVersion()
fhammerl marked this conversation as resolved.
Show resolved Hide resolved
let gitOutput = await this.execGit(['version'])
let stdout = gitOutput.stdout.trim()
if (!stdout.includes('\n')) {
const match = stdout.match(/\d+\.\d+(\.\d+)?/)
if (match) {
gitVersion = new GitVersion(match[0])
this.gitVersion = new GitVersion(match[0])
}
}
if (!gitVersion.isValid()) {
if (!this.gitVersion.isValid()) {
throw new Error('Unable to determine git version')
}

// Minimum git version
if (!gitVersion.checkMinimum(MinimumGitVersion)) {
if (!this.gitVersion.checkMinimum(MinimumGitVersion)) {
throw new Error(
`Minimum required git version is ${MinimumGitVersion}. Your git ('${this.gitPath}') is ${gitVersion}`
`Minimum required git version is ${MinimumGitVersion}. Your git ('${this.gitPath}') is ${this.gitVersion}`
)
}

Expand Down Expand Up @@ -606,16 +614,14 @@ class GitCommandManager {

this.doSparseCheckout = doSparseCheckout
if (this.doSparseCheckout) {
// The `git sparse-checkout` command was introduced in Git v2.25.0
const minimumGitSparseCheckoutVersion = new GitVersion('2.25')
if (!gitVersion.checkMinimum(minimumGitSparseCheckoutVersion)) {
if (!this.gitVersion.checkMinimum(MinimumGitSparseCheckoutVersion)) {
fhammerl marked this conversation as resolved.
Show resolved Hide resolved
throw new Error(
`Minimum Git version required for sparse checkout is ${minimumGitSparseCheckoutVersion}. Your git ('${this.gitPath}') is ${gitVersion}`
`Minimum Git version required for sparse checkout is ${MinimumGitSparseCheckoutVersion}. Your git ('${this.gitPath}') is ${this.gitVersion}`
)
}
}
// Set the user agent
const gitHttpUserAgent = `git/${gitVersion} (github-actions-checkout)`
const gitHttpUserAgent = `git/${this.gitVersion} (github-actions-checkout)`
core.debug(`Set git useragent to: ${gitHttpUserAgent}`)
this.gitEnv['GIT_HTTP_USER_AGENT'] = gitHttpUserAgent
}
Expand Down
8 changes: 6 additions & 2 deletions src/git-source-provider.ts
Expand Up @@ -9,7 +9,7 @@ import * as path from 'path'
import * as refHelper from './ref-helper'
import * as stateHelper from './state-helper'
import * as urlHelper from './url-helper'
import {IGitCommandManager} from './git-command-manager'
import {MinimumGitSparseCheckoutVersion, IGitCommandManager} from './git-command-manager'
import {IGitSourceSettings} from './git-source-settings'

export async function getSource(settings: IGitSourceSettings): Promise<void> {
Expand Down Expand Up @@ -209,7 +209,11 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {

// Sparse checkout
if (!settings.sparseCheckout) {
await git.disableSparseCheckout()
let gitVersion = await git.version()
// no need to disable sparse-checkout if the installed git runtime doesn't even support it.
if (gitVersion.checkMinimum(MinimumGitSparseCheckoutVersion)) {
await git.disableSparseCheckout()
}
} else {
core.startGroup('Setting up sparse checkout')
if (settings.sparseCheckoutConeMode) {
Expand Down