Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
472e5ee
feat: fix handling of gitlab repos
sarahetter Feb 13, 2026
a2b7181
fix: types
sarahetter Feb 13, 2026
7e420b0
Merge branch 'main' into sarahetter/gitlab
sarahetter Feb 18, 2026
bcddb62
chore: improve reliability of deploy integration tests (#7951)
serhalp Feb 18, 2026
7fda9dd
feat: begin integrating `@netlify/dev` (#7950)
eduardoboucas Feb 19, 2026
ac45c4d
feat!: remove `sites:create-template` command (#7946)
sarahetter Feb 19, 2026
94c0146
chore(ci): fix flakey integration tests (#7958)
eduardoboucas Feb 21, 2026
6adbd47
fix: remove dead path
sarahetter Feb 23, 2026
ebc8b07
Merge branch 'main' into sarahetter/gitlab
sarahetter Feb 23, 2026
4b636c3
Merge branch 'main' into sarahetter/gitlab
sarahetter Mar 31, 2026
f49c2e8
Merge remote-tracking branch 'origin/main' into sarahetter/gitlab
sarahetter May 5, 2026
f849e35
test: address review feedback on get-repo-data and config-manual tests
sarahetter May 5, 2026
8a3ba28
Merge branch 'sarahetter/gitlab' of github.com:netlify/cli into sarah…
sarahetter May 5, 2026
73b5ecb
Merge branch 'main' into sarahetter/gitlab
sarahetter May 7, 2026
deb8939
Merge branch 'main' into sarahetter/gitlab
sarahetter Jun 2, 2026
82b4aad
Merge branch 'main' into sarahetter/gitlab
sarahetter Jun 9, 2026
93db64d
Merge branch 'main' into sarahetter/gitlab
sarahetter Jun 10, 2026
9544148
fix: fallback to manual provider for unsupported Git hosts
jaredm563 Jun 12, 2026
69318bb
Merge branch 'main' into sarahetter/gitlab
jaredm563 Jun 12, 2026
f4a009d
fix: remove bold formatting from package name in db-status output and…
jaredm563 Jun 12, 2026
c31135d
Merge branch 'sarahetter/gitlab' of https://github.com/netlify/cli in…
jaredm563 Jun 12, 2026
94f015a
test: update init command tests to use github provider instead of manual
jaredm563 Jun 16, 2026
7952c30
remove unrelated churn
jaredm563 Jun 16, 2026
352c17a
Merge branch 'main' into sarahetter/gitlab
jaredm563 Jun 16, 2026
64c7490
Merge branch 'main' into sarahetter/gitlab
sarahetter Jun 18, 2026
ea313e2
Merge branch 'main' into sarahetter/gitlab
sarahetter Jun 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions src/utils/init/config-manual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ const addDeployHook = async (deployHook: string | undefined): Promise<boolean> =
return deployHookAdded
}

const isSupportedProvider = (provider: string | null): provider is 'github' | 'gitlab' =>
provider === 'github' || provider === 'gitlab'

export default async function configManual({
command,
repoData,
Expand All @@ -86,9 +89,9 @@ export default async function configManual({
const deployKey = await createDeployKey({ api })
await addDeployKey(deployKey)

const repoPath = await getRepoPath({ repoData })
const repoPath = repoData.repo ?? (await getRepoPath({ repoData }))
const repo = {
provider: 'manual',
provider: isSupportedProvider(repoData.provider) ? repoData.provider : 'manual',
repo_path: repoPath,
repo_branch: repoData.branch,
allowed_branches: [repoData.branch],
Expand Down
24 changes: 12 additions & 12 deletions tests/integration/commands/init/init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ describe.concurrent('commands/init', () => {
allowed_branches: ['main'],
cmd: command,
dir: publish,
provider: 'manual',
provider: 'github',
repo_branch: 'main',
repo_path: 'git@github.com:owner/repo.git',
repo_path: 'owner/repo',
functions_dir: defaultFunctionsDirectory,
},
},
Expand Down Expand Up @@ -184,9 +184,9 @@ describe.concurrent('commands/init', () => {
allowed_branches: ['main'],
cmd: command,
dir: publish,
provider: 'manual',
provider: 'github',
repo_branch: 'main',
repo_path: 'git@github.com:owner/repo.git',
repo_path: 'owner/repo',
functions_dir: defaultFunctionsDirectory,
},
},
Expand Down Expand Up @@ -368,9 +368,9 @@ describe.concurrent('commands/init', () => {
allowed_branches: ['main'],
cmd: command,
dir: publish,
provider: 'manual',
provider: 'github',
repo_branch: 'main',
repo_path: 'git@github.com:owner/repo.git',
repo_path: 'owner/repo',
functions_dir: defaultFunctionsDirectory,
},
},
Expand Down Expand Up @@ -473,9 +473,9 @@ describe.concurrent('commands/init', () => {
allowed_branches: ['main'],
cmd: command,
dir: publish,
provider: 'manual',
provider: 'github',
repo_branch: 'main',
repo_path: 'git@github.com:owner/repo.git',
repo_path: 'owner/repo',
functions_dir: defaultFunctionsDirectory,
},
},
Expand Down Expand Up @@ -563,9 +563,9 @@ describe.concurrent('commands/init', () => {
allowed_branches: ['main'],
cmd: command,
dir: publish,
provider: 'manual',
provider: 'github',
repo_branch: 'main',
repo_path: 'git@github.com:owner/repo.git',
repo_path: 'owner/repo',
functions_dir: defaultFunctionsDirectory,
},
},
Expand Down Expand Up @@ -666,9 +666,9 @@ describe.concurrent('commands/init', () => {
allowed_branches: ['main'],
cmd: command,
dir: publish,
provider: 'manual',
provider: 'github',
repo_branch: 'main',
repo_path: 'git@github.com:owner/repo.git',
repo_path: 'owner/repo',
functions_dir: defaultFunctionsDirectory,
},
},
Expand Down
143 changes: 143 additions & 0 deletions tests/unit/utils/get-repo-data.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'

import getRepoData from '../../../src/utils/get-repo-data.js'

const mockGitConfig = vi.fn()
const mockFindUp = vi.fn()
const mockGitRepoInfo = vi.fn()

vi.mock('gitconfiglocal', () => ({
default: (workingDir: string, cb: (err: Error | null, config: unknown) => void) => {
try {
cb(null, mockGitConfig(workingDir))
} catch (err) {
cb(err as Error, null)
}
},
}))

vi.mock('find-up', () => ({
findUp: (...args: unknown[]): unknown => mockFindUp(...args),
}))

vi.mock('git-repo-info', () => ({
default: (): unknown => mockGitRepoInfo(),
}))

vi.mock('../../../src/utils/command-helpers.js', () => ({
log: vi.fn(),
}))

describe('getRepoData', () => {
beforeEach(() => {
vi.clearAllMocks()
mockFindUp.mockResolvedValue('/test/.git')
mockGitRepoInfo.mockReturnValue({ branch: 'main' })
})

it('parses GitHub SSH URLs', async () => {
mockGitConfig.mockReturnValue({ remote: { origin: { url: 'git@github.com:ownername/test.git' } } })

const result = await getRepoData({ workingDir: '/test' })

expect(result).toEqual({
name: 'test',
owner: 'ownername',
repo: 'ownername/test',
url: 'git@github.com:ownername/test.git',
branch: 'main',
provider: 'github',
httpsUrl: 'https://github.com/ownername/test',
})
})

it('parses GitLab SSH URLs', async () => {
mockGitConfig.mockReturnValue({ remote: { origin: { url: 'git@gitlab.com:ownername/test.git' } } })

const result = await getRepoData({ workingDir: '/test' })

expect(result).toEqual({
name: 'test',
owner: 'ownername',
repo: 'ownername/test',
url: 'git@gitlab.com:ownername/test.git',
branch: 'main',
provider: 'gitlab',
httpsUrl: 'https://gitlab.com/ownername/test',
})
})

it('parses GitHub HTTPS URLs', async () => {
mockGitConfig.mockReturnValue({ remote: { origin: { url: 'https://github.com/ownername/test.git' } } })

const result = await getRepoData({ workingDir: '/test' })

expect(result).toMatchObject({
provider: 'github',
repo: 'ownername/test',
httpsUrl: 'https://github.com/ownername/test',
})
})

it('parses GitLab HTTPS URLs', async () => {
mockGitConfig.mockReturnValue({ remote: { origin: { url: 'https://gitlab.com/ownername/test.git' } } })

const result = await getRepoData({ workingDir: '/test' })

expect(result).toMatchObject({
provider: 'gitlab',
repo: 'ownername/test',
httpsUrl: 'https://gitlab.com/ownername/test',
})
})

it('uses host as provider for unknown Git hosts', async () => {
mockGitConfig.mockReturnValue({
remote: { origin: { url: 'git@custom-git.example.com:user/test.git' } },
})

const result = await getRepoData({ workingDir: '/test' })

expect(result).toMatchObject({
provider: 'custom-git.example.com',
repo: 'user/test',
httpsUrl: 'https://custom-git.example.com/user/test',
})
})

it('uses the specified remote name when provided', async () => {
mockGitConfig.mockReturnValue({
remote: {
origin: { url: 'git@github.com:owner/origin-repo.git' },
upstream: { url: 'git@gitlab.com:owner/upstream-repo.git' },
},
})

const result = await getRepoData({ workingDir: '/test', remoteName: 'upstream' })

expect(result).toMatchObject({
provider: 'gitlab',
repo: 'owner/upstream-repo',
})
})

it('returns an error when no Git remote is found', async () => {
mockFindUp.mockResolvedValue(undefined)
mockGitConfig.mockReturnValue({ remote: {} })

const result = await getRepoData({ workingDir: '/test' })

expect(result).toEqual({ error: 'No Git remote found' })
})

it('returns an error when the requested remote is not defined', async () => {
mockGitConfig.mockReturnValue({ remote: { origin: { url: 'git@github.com:owner/repo.git' } } })

const result = await getRepoData({ workingDir: '/test', remoteName: 'missing' })

expect(result).toEqual({
error:
'The specified remote "missing" is not defined in Git repo. Please use --git-remote-name flag to specify a remote.',
})
})
Comment thread
sarahetter marked this conversation as resolved.
})
Loading
Loading