I have a yaml Azure DevOps pipeline as below which is trying to consume a nuget feed from another organization.
As you can see I am using the nugetauthenticate@1 task to create valid credentials using a Service Connection created by a user in the target organization.
I have a docker file called by the pipeline in which I install the artifacts credential provider via their sh script.
I am setting the JSON environment variable in the dockerfile with a valid PAT passed into the docker task:
arguments: '--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)'
n.b. I have tried using the cred provider variable $(VSS_NUGET_ACCESSTOKEN) and by using my own pipeline variable containing a valid PAT.
When I call dotnet restore in the docker step the step faults with:
error NU1301: Unable to load the service index for source https://pkgs.dev.azure.com/{org}/_packaging/{feed}/nuget/v3/index.json
I've turned on verbose logging and the credential provider is using the provided configuration but I don't get an Auth (401) issue, just an error hitting the nuget index page feed so i think its not even getting a chance to authenticate.
Any advice would be greatly appreciated.
Pipeline:
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
NUGET.PLUGIN.HANDSHAKE.TIMEOUT.IN.SECONDS: 20
NUGET.PLUGIN.REQUEST.TIMEOUT.IN.SECONDS: 20
steps:
- task: NuGetAuthenticate@1
inputs:
nuGetServiceConnections: 'nuget-feed'
- task: NodeTool@0
inputs:
versionSpec: '18.17.1'
- task: DotNetCoreCLI@2
inputs:
command: 'build'
arguments: 'xxx/xxx.sln'
- task: Docker@2
inputs:
command: 'build'
Dockerfile: 'xxx/xxx/Dockerfile'
buildContext: 'xxx'
arguments: '--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
Docker file:
FROM mcr.microsoft.com/dotnet/aspnet:6.0.14-bullseye-slim-amd64 AS base
ARG FEED_ACCESSTOKEN
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build
ENV NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=60
ENV NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=60
RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh | sh
WORKDIR /src
COPY ["xxx/xxx.csproj", "xxx/"]
COPY ["xxx/nuget.config", "xxx/"]
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{\"endpointCredentials\": [{\"endpoint\":\"https://pkgs.dev.azure.com/{org}/_packaging/{feed}/nuget/v3/index.json\", \"username\":\"docker\", \"password\":\"${FEED_ACCESSTOKEN}\"}]}"
RUN echo $VSS_NUGET_EXTERNAL_FEED_ENDPOINTS
RUN dotnet restore "xxx/xxx.csproj" --verbosity detailed
I can reproduce the same error using the Dockerfile you shared.
After checking the log, I found the password is empty in the endpointCredentials command. I added the command RUN echo "Access Token: $FEED_ACCESSTOKEN"
to confirm it.
After this, I moved the line ARG FEED_ACCESSTOKEN
after FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build
.
New Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:6.0.14-bullseye-slim-amd64 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build
ARG FEED_ACCESSTOKEN
ENV NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=60
ENV NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=60
RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh | sh
WORKDIR /src
COPY ["xxx/xxx.csproj", "xxx/"]
COPY ["xxx/nuget.config", "xxx/"]
RUN echo "Access Token: $FEED_ACCESSTOKEN"
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{\"endpointCredentials\": [{\"endpoint\":\"https://pkgs.dev.azure.com/{org}/_packaging/{feed}/nuget/v3/index.json\", \"username\":\"docker\", \"password\":\"${FEED_ACCESSTOKEN}\"}]}"
RUN echo $VSS_NUGET_EXTERNAL_FEED_ENDPOINTS
RUN dotnet restore "xxx/xxx.csproj" --verbosity detailed
This time, the password is not empty and the restore step is successful.
Cause of the issue:
ARG
variables are scoped to the stage where they are defined. So, you should move this line to the build stage where you use it.
If you want to share variable in multi-stage Dockerfile, each stage must include the ARG
instruction. You can refer this question for more information about Share variable in multi-stage Dockerfile.