Cribber
Cribber

Reputation: 2943

Installing packages from Azure DevOps Artifact Feed in a Azure Pipeline

I have two repositories.

I can install it locally, but the pipeline of the second package fails. When the pipeline fails, I get the following error:

401 Client Error: Unauthorized for url: 
https://pkgs.dev.azure.com/<company>/<some-numbers>/_packaging/<some-numbers>/pypi/download/<mypackage>/0.0.1.9/<mypackage>-0.0.1.9-py3-none-any.whl#sha256=<some-numbers>

---------------------------------- SETUP ----------------------------------

I added the feed as a secondary source to the pyproject.toml of my second repository, this allows me to successfully install the first package with poetry add <firstpackage> and poetry install for my local IDE:

[[tool.poetry.source]]
name = "azure"
url = "https://pkgs.dev.azure.com/<company>/<some-numbers>/_packaging/<feed-name>/pypi/simple/"
secondary = true

YAML script to install packages via poetry - works for the first repository, but not for the second repository which needs to install the first package from the Azure DevOps artifcats feed (the first installs everything from pypi.org):

- script: |
    python -m pip install -U pip
    pip install poetry==1.1.3  # Install poetry via pip to pin the version
    poetry install
  displayName: Install software

YAML script to publish a package to an Azure DevOps artifact feed (with a personal access token as authentification) - works:

- script: |
    poetry config repositories.azure https://pkgs.dev.azure.com/<company>/<somenumbers>/_packaging/<feed-name>/pypi/upload/
    poetry config http-basic.azure usernamedoesnotmatter $(pat)
    poetry publish --repository azure
    exit 0
  displayName: Publish package

Upvotes: 3

Views: 4874

Answers (3)

DigitalDirk
DigitalDirk

Reputation: 190

Another solution uses the predefined system variable $(System.AccessToken). This variable is available in both build pipelines and release pipeline. See link to azure documentation.

A detailed description (for release-pipelines) is set up in this article.

You can use it like this in the build pipeline yaml:

poetry config http-basic.azure userNameDoesntMatter $(System.AccessToken)
poetry install

The system access token is coming from the Azure DevOps system. However, it does require some additional setup: you need to grant the "AddPackage" permission to the DevOps service principal in order to enable him to publish to the feed. In the settings of the specific feed, go to the "permissions" tab and assign the role Collaborator to the service principal <your_devops_workspace> Build Service (<your_Azure_DevOps_Account>).

An advantage of using the System token + giving the role to the SP, is that PATs require regular updates as they expire after a year at most.

Security wise, using a secured PAT as a pipeline variable is not less safe than using the SP, but it reduces complexity.

Upvotes: 3

Jostein L
Jostein L

Reputation: 344

I am not checking my Personal Access Token (PAT) into my repository.

pyproject.toml (partial):

[[tool.poetry.source]]
name = "azure"
url = "https://pkgs.dev.azure.com/<company>/<some-numbers>/_packaging/<feed-name>/pypi/simple/"
secondary = true

I added the PipAuthenticate@1 task that sets the PIP_EXTRA_INDEX_URL environment variable that contains a PAT. In the script, I extract the PAT and use it to configure poetry.

azure-pipelines.yaml (partial):

  - task: PipAuthenticate@1
    displayName: 'Pip Authenticate'
    inputs:
      artifactFeeds: '<some-numbers>/<feed-name>'
      onlyAddExtraIndex: True


  - script: |
      python -m pip install --upgrade pip
      pip install poetry
      export PAT=$(echo "$PIP_EXTRA_INDEX_URL" | sed 's/.*build:\(.*\)@pkgs.*/\1/')
      poetry config http-basic.azure build "$PAT"
      poetry install
    displayName: "Install dependencies"

Upvotes: 2

Cribber
Cribber

Reputation: 2943

Turns out, I just needed to configure poetry in the pipeline before the install for the second repository - same as I did locally, some long time ago (and forgot about it).

- script: |
    python -m pip install -U pip
    pip install poetry==1.1.3  # Install poetry via pip to pin the version
    
    # configuring the feed as a secondary source for poetry
    poetry config repositories.azure https://pkgs.dev.azure.com/<company>/<some-numbers>/_packaging/<feed-name>/pypi/simple/
    poetry config http-basic.azure userNameDoesntMatter $(pat)  

    poetry install    
    displayName: Install software

Upvotes: 0

Related Questions