Skip to content

Commit

Permalink
feat(pep621): set Git insteadOf directives when updating pdm/uv locks (
Browse files Browse the repository at this point in the history
  • Loading branch information
maxbrunet authored Nov 14, 2024
1 parent 2862f76 commit 22880e9
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 0 deletions.
60 changes: 60 additions & 0 deletions lib/modules/manager/pep621/processors/pdm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { fs, mockedFunction } from '../../../../../test/util';
import { GlobalConfig } from '../../../../config/global';
import type { RepoGlobalConfig } from '../../../../config/types';
import { logger } from '../../../../logger';
import * as hostRules from '../../../../util/host-rules';
import { getPkgReleases as _getPkgReleases } from '../../../datasource';
import type { UpdateArtifactsConfig } from '../../types';
import { depTypes } from '../utils';
Expand Down Expand Up @@ -290,5 +291,64 @@ describe('modules/manager/pep621/processors/pdm', () => {
},
]);
});

it('sets Git environment variables', async () => {
hostRules.add({
matchHost: 'https://example.com',
username: 'user',
password: 'pass',
});
const execSnapshots = mockExecAll();
GlobalConfig.set(adminConfig);
fs.getSiblingFileName.mockReturnValueOnce('pdm.lock');
fs.readLocalFile.mockResolvedValueOnce('test content');
fs.readLocalFile.mockResolvedValueOnce('changed test content');
// python
getPkgReleases.mockResolvedValueOnce({
releases: [{ version: '3.11.1' }, { version: '3.11.2' }],
});
// pdm
getPkgReleases.mockResolvedValueOnce({
releases: [{ version: 'v2.6.1' }, { version: 'v2.5.0' }],
});

const result = await processor.updateArtifacts(
{
packageFileName: 'folder/pyproject.toml',
newPackageFileContent: '',
config: {
updateType: 'lockFileMaintenance',
},
updatedDeps: [],
},
{},
);
expect(result).toEqual([
{
file: {
contents: 'changed test content',
path: 'pdm.lock',
type: 'addition',
},
},
]);
expect(execSnapshots).toMatchObject([
{
cmd: 'pdm update --no-sync --update-eager',
options: {
cwd: '/tmp/github/some/repo/folder',
env: {
GIT_CONFIG_COUNT: '3',
GIT_CONFIG_KEY_0: 'url.https://user:[email protected]/.insteadOf',
GIT_CONFIG_KEY_1: 'url.https://user:[email protected]/.insteadOf',
GIT_CONFIG_KEY_2: 'url.https://user:[email protected]/.insteadOf',
GIT_CONFIG_VALUE_0: 'ssh://[email protected]/',
GIT_CONFIG_VALUE_1: '[email protected]:',
GIT_CONFIG_VALUE_2: 'https://example.com/',
},
},
},
]);
});
});
});
5 changes: 5 additions & 0 deletions lib/modules/manager/pep621/processors/pdm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { logger } from '../../../../logger';
import { exec } from '../../../../util/exec';
import type { ExecOptions, ToolConstraint } from '../../../../util/exec/types';
import { getSiblingFileName, readLocalFile } from '../../../../util/fs';
import { getGitEnvironmentVariables } from '../../../../util/git/auth';
import { Result } from '../../../../util/result';
import { PypiDatasource } from '../../../datasource/pypi';
import type {
Expand Down Expand Up @@ -116,8 +117,12 @@ export class PdmProcessor implements PyProjectProcessor {
constraint: config.constraints?.pdm,
};

const extraEnv = {
...getGitEnvironmentVariables(['pep621']),
};
const execOptions: ExecOptions = {
cwdFile: packageFileName,
extraEnv,
docker: {},
userConfiguredEnv: config.env,
toolConstraints: [pythonConstraint, pdmConstraint],
Expand Down
7 changes: 7 additions & 0 deletions lib/modules/manager/pep621/processors/uv.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,13 @@ describe('modules/manager/pep621/processors/uv', () => {
cmd: 'uv lock --upgrade-package dep1 --upgrade-package dep2 --upgrade-package dep3 --upgrade-package dep4',
options: {
env: {
GIT_CONFIG_COUNT: '3',
GIT_CONFIG_KEY_0: 'url.https://user:[email protected]/.insteadOf',
GIT_CONFIG_KEY_1: 'url.https://user:[email protected]/.insteadOf',
GIT_CONFIG_KEY_2: 'url.https://user:[email protected]/.insteadOf',
GIT_CONFIG_VALUE_0: 'ssh://[email protected]/',
GIT_CONFIG_VALUE_1: '[email protected]:',
GIT_CONFIG_VALUE_2: 'https://example.com/',
UV_EXTRA_INDEX_URL:
'https://foobar.com/ https://user:[email protected]/',
},
Expand Down
2 changes: 2 additions & 0 deletions lib/modules/manager/pep621/processors/uv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { HostRule } from '../../../../types';
import { exec } from '../../../../util/exec';
import type { ExecOptions, ToolConstraint } from '../../../../util/exec/types';
import { getSiblingFileName, readLocalFile } from '../../../../util/fs';
import { getGitEnvironmentVariables } from '../../../../util/git/auth';
import { find } from '../../../../util/host-rules';
import { Result } from '../../../../util/result';
import { parseUrl } from '../../../../util/url';
Expand Down Expand Up @@ -129,6 +130,7 @@ export class UvProcessor implements PyProjectProcessor {
};

const extraEnv = {
...getGitEnvironmentVariables(['pep621']),
...getUvExtraIndexUrl(updateArtifact.updatedDeps),
};
const execOptions: ExecOptions = {
Expand Down
17 changes: 17 additions & 0 deletions lib/modules/manager/pep621/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,20 @@ Available `depType`s:
- `tool.uv.dev-dependencies`
- `tool.uv.sources`
- `tool.hatch.envs.<env-name>`

### Private Modules Authentication

Before running the `pdm` or `uv` commands to update the `pdm.lock` or `uv.lock` respectively, Renovate exports `git` [`insteadOf`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-urlltbasegtinsteadOf) directives in environment variables.

Renovate uses this logic before it updates any "artifacts":

The token from the `hostRules` entry matching `hostType=github` and `matchHost=api.github.com` is added as the default authentication for `github.com`.
For those running against `github.com`, this token will be the default platform token.

Next, all `hostRules` with both a token or username/password and `matchHost` will be fetched, except for any `github.com` one from above.

Rules from this list are converted to environment variable directives if they match _any_ of these characteristics:

- No `hostType` is defined, or
- `hostType` is `pep621`, or
- `hostType` is a platform (`github`, `gitlab`, `azure`, etc.)

0 comments on commit 22880e9

Please sign in to comment.