From 998d7176d0e83b3a407cf919c0eeb21988bcd753 Mon Sep 17 00:00:00 2001 From: Mate Molnar Date: Thu, 27 Aug 2026 18:24:02 +0200 Subject: [PATCH] Export Repox index env vars from config-pip for pipx, mise, and uv. pip.conf alone is ignored by pipx, mise, and uv; export PIP_INDEX_URL, UV_DEFAULT_INDEX, MISE_PIPX_REGISTRY_URL, and PIP_CONFIG_FILE after writing pip.conf and mask authenticated URLs in logs. --- README.md | 6 ++++++ config-pip/config.sh | 31 +++++++++++++++++++++++-------- spec/config-pip_spec.sh | 35 +++++++++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 13faa798..1d867eca 100644 --- a/README.md +++ b/README.md @@ -1213,7 +1213,9 @@ jobs: Configure pip build environment with build number, authentication, and default settings. This action configures pip to pull packages from the internal JFrog Artifactory registry instead of the default PyPI. +It writes `~/.pip/pip.conf` and exports environment variables so pip, uv, pipx, and mise also resolve Python packages from Repox. +> **Note:** Run `config-pip` **before** `setup-python`, `mise`, `pipx`, or `uv` in the same job. Those tools read `PIP_INDEX_URL`, `UV_DEFAULT_INDEX`, and `MISE_PIPX_REGISTRY_URL` at install time; `pip.conf` alone is not enough for them. > **Note:** This action automatically calls [`get-build-number`](#get-build-number) to manage the build number. > **Note:** This action replaces the deprecated `configure-pipx-repox` action from `sonarqube-cloud-github-actions` repository. @@ -1286,6 +1288,10 @@ steps: | `ARTIFACTORY_ACCESS_TOKEN` | Access token for Artifactory authentication | | `ARTIFACTORY_USERNAME` | Username for Artifactory authentication | | `ARTIFACTORY_URL` | Artifactory (Repox) URL. E.x.: `https://repox.jfrog.io/artifactory` | +| `PIP_INDEX_URL` | Authenticated Repox simple index for pip and setup-python bootstrap | +| `UV_DEFAULT_INDEX` | Authenticated Repox simple index for uv | +| `MISE_PIPX_REGISTRY_URL` | Authenticated Repox index template for mise pipx backends | +| `PIP_CONFIG_FILE` | Path to the generated `pip.conf` | See also [`get-build-number`](#get-build-number) output environment variables. diff --git a/config-pip/config.sh b/config-pip/config.sh index 4bb77559..d63e542d 100755 --- a/config-pip/config.sh +++ b/config-pip/config.sh @@ -7,26 +7,41 @@ # - ARTIFACTORY_ACCESS_TOKEN: Access token to read Repox repositories # # GitHub Actions auto-provided: -# - GITHUB_REPOSITORY: Repository name in format "owner/repo" +# - GITHUB_ENV: Path to GitHub Actions environment file set -euo pipefail -: "${ARTIFACTORY_URL:?}" "${ARTIFACTORY_USERNAME:?}" "${ARTIFACTORY_ACCESS_TOKEN:?}" +: "${ARTIFACTORY_URL:?}" "${ARTIFACTORY_USERNAME:?}" "${ARTIFACTORY_ACCESS_TOKEN:?}" "${GITHUB_ENV:?}" configure_pip() { echo "Configuring pip to use Artifactory..." - # Extract the host from ARTIFACTORY_URL - local repox_host="${ARTIFACTORY_URL#https://}" + local repox_host pip_conf_file authenticated_index registry_url + + repox_host="${ARTIFACTORY_URL#https://}" repox_host="${repox_host#http://}" echo "Repox host: $repox_host" - mkdir -p "$HOME/.pip" - cat > "${HOME}/.pip/pip.conf" < "$pip_conf_file" <> "$GITHUB_ENV" + return 0 } diff --git a/spec/config-pip_spec.sh b/spec/config-pip_spec.sh index 6a14749f..7fc981bd 100755 --- a/spec/config-pip_spec.sh +++ b/spec/config-pip_spec.sh @@ -2,16 +2,20 @@ eval "$(shellspec - -c) exit 1" # Set up environment variables -export GITHUB_REPOSITORY="my-org/test-project" export GITHUB_ENV=/dev/null export GITHUB_OUTPUT=/dev/null export ARTIFACTORY_URL="https://repox.jfrog.io/artifactory" export ARTIFACTORY_USERNAME="test-user" export ARTIFACTORY_ACCESS_TOKEN="test-token" +AUTHENTICATED_INDEX="https://test-user:test-token@repox.jfrog.io/artifactory/api/pypi/sonarsource-pypi/simple" +MISE_REGISTRY_URL="${AUTHENTICATED_INDEX}/{}/" + # Expected output messages MESSAGE_CONFIGURING_PIP="Configuring pip to use Artifactory..." MESSAGE_REPOX_HOST="Repox host: repox.jfrog.io/artifactory" +MESSAGE_MASK_INDEX="::add-mask::${AUTHENTICATED_INDEX}" +MESSAGE_MASK_REGISTRY="::add-mask::${MISE_REGISTRY_URL}" Describe 'config-pip/config.sh' It 'does not run main when sourced' @@ -44,28 +48,45 @@ Describe 'configure_pip()' It 'creates pip config directory, file and correct content' When call configure_pip The status should be success - The lines of output should equal 3 + The lines of output should equal 5 The lines of error should equal 0 The line 1 should equal "$MESSAGE_CONFIGURING_PIP" The line 2 should equal "$MESSAGE_REPOX_HOST" The line 3 should start with "Configuration file: " The line 3 should end with "/.pip/pip.conf" + The line 4 should equal "$MESSAGE_MASK_INDEX" + The line 5 should equal "$MESSAGE_MASK_REGISTRY" The path "${HOME}/.pip" should be directory The path "${HOME}/.pip/pip.conf" should be file The contents of file "${HOME}/.pip/pip.conf" should equal "[global] -index-url = https://test-user:test-token@repox.jfrog.io/artifactory/api/pypi/sonarsource-pypi/simple" +index-url = ${AUTHENTICATED_INDEX}" + End + + It 'exports index environment variables for pip, uv, mise, and pipx' + GITHUB_ENV=$(mktemp) + export GITHUB_ENV + When call configure_pip + The status should be success + The lines of output should equal 5 + The contents of file "$GITHUB_ENV" should include "PIP_INDEX_URL=${AUTHENTICATED_INDEX}" + The contents of file "$GITHUB_ENV" should include "UV_DEFAULT_INDEX=${AUTHENTICATED_INDEX}" + The contents of file "$GITHUB_ENV" should include "MISE_PIPX_REGISTRY_URL=${MISE_REGISTRY_URL}" + The contents of file "$GITHUB_ENV" should include "PIP_CONFIG_FILE=${HOME}/.pip/pip.conf" + rm -f "$GITHUB_ENV" End It 'handles URL with custom port' export ARTIFACTORY_URL="https://repox.jfrog.io:8080/artifactory" When call configure_pip The status should be success - The lines of output should equal 3 + The lines of output should equal 5 The lines of error should equal 0 The line 1 should equal "$MESSAGE_CONFIGURING_PIP" The line 2 should equal "Repox host: repox.jfrog.io:8080/artifactory" The line 3 should start with "Configuration file: " The line 3 should end with "/.pip/pip.conf" + The line 4 should equal "::add-mask::https://test-user:test-token@repox.jfrog.io:8080/artifactory/api/pypi/sonarsource-pypi/simple" + The line 5 should equal "::add-mask::https://test-user:test-token@repox.jfrog.io:8080/artifactory/api/pypi/sonarsource-pypi/simple/{}/" The contents of file "${HOME}/.pip/pip.conf" should equal "[global] index-url = https://test-user:test-token@repox.jfrog.io:8080/artifactory/api/pypi/sonarsource-pypi/simple" End @@ -80,14 +101,16 @@ Describe 'main()' export ARTIFACTORY_ACCESS_TOKEN="my-secret-token" When run script config-pip/config.sh The status should be success - The lines of output should equal 5 + The lines of output should equal 7 The lines of error should equal 0 The line 1 should equal "::group::Configure pip" The line 2 should equal "$MESSAGE_CONFIGURING_PIP" The line 3 should equal "$MESSAGE_REPOX_HOST" The line 4 should start with "Configuration file: " The line 4 should end with "/.pip/pip.conf" - The line 5 should equal "::endgroup::" + The line 5 should equal "::add-mask::https://my-user:my-secret-token@repox.jfrog.io/artifactory/api/pypi/sonarsource-pypi/simple" + The line 6 should equal "::add-mask::https://my-user:my-secret-token@repox.jfrog.io/artifactory/api/pypi/sonarsource-pypi/simple/{}/" + The line 7 should equal "::endgroup::" The path "${HOME}/.pip/pip.conf" should be file The contents of file "${HOME}/.pip/pip.conf" should equal "[global] index-url = https://my-user:my-secret-token@repox.jfrog.io/artifactory/api/pypi/sonarsource-pypi/simple"