Summary
One of my defined CI/CD variables value doesn't pass to pipeline job script, though others pass correct.
The variable name I'm talking about is APPSETTINGS
, see its usage at pre-deploy_job
.
I'm trying to pass its value as a build argument for docker there. Other variables are HOST
, USER
, ID_RSA
and they work fine.
What have I missed?
.gitlab-ci.yml
default:
image: mcr.microsoft.com/dotnet/sdk:7.0
stages:
- build
- test
- pre-deploy
- deploy
variables:
OBJECTS_DIRECTORY: 'obj'
NUGET_PACKAGES_DIRECTORY: '.nuget'
SOURCE_CODE_PATH: '*/*/'
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
DOCKER_DRIVER: overlay2
cache:
key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
paths:
- '$SOURCE_CODE_PATH$OBJECTS_DIRECTORY/project.assets.json'
- '$SOURCE_CODE_PATH$OBJECTS_DIRECTORY/*.csproj.nuget.*'
- '$NUGET_PACKAGES_DIRECTORY'
policy: pull-push
before_script:
- 'dotnet restore --packages $NUGET_PACKAGES_DIRECTORY'
- 'echo $APPSETTINGS'
build_job:
stage: build
only:
- branches
script:
- 'dotnet build --no-restore'
test_job:
stage: test
only:
- branches
script:
- 'dotnet test ./Tests --no-restore --test-adapter-path:. --logger:"junit;LogFilePath=..\artifacts\{assembly}-test-result.xml;MethodFormat=Class;FailureBodyFormat=Verbose"'
artifacts:
when: always
paths:
- ./**/*test-result.xml
reports:
junit:
- ./**/*test-result.xml
pre-deploy_job:
image: docker:stable
services:
- docker:dind
stage: pre-deploy
only:
- master
- dev
before_script:
- docker login ${CI_REGISTRY} -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD}
script:
- docker build -t ${CI_REGISTRY}/${CI_PROJECT_PATH}:latest --build-arg APPSETTINGS=${APPSETTINGS} --no-cache .
- docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}:latest
after_script:
- docker logout ${CI_REGISTRY}
deploy_job:
stage: deploy
only:
- master
- dev
script:
- chmod og= $ID_RSA
- apt-get update
- apt-get install -y openssh-client
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $USER@$HOST "docker login ${CI_REGISTRY} -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD}"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $USER@$HOST "docker pull ${CI_REGISTRY}/${CI_PROJECT_PATH}:latest"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $USER@$HOST "docker container rm -f tech-connect || true"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $USER@$HOST "docker run -d -p 80:80 --name tech-connect ${CI_REGISTRY}/${CI_PROJECT_PATH}:latest"
environment:
name: staging
url: $HOST
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
ARG APPSETTINGS
RUN [ "sh", "-c", "echo $APPSETTINGS" ]
WORKDIR /src
COPY ["TC/TC.csproj", "TC/"]
RUN dotnet restore "TC/TC.csproj"
COPY . .
WORKDIR "/src/TC"
RUN dotnet build "TC.csproj" -c Release -o /app/build
RUN cp -f $APPSETTINGS /app/build/appsettings.json
FROM build AS publish
RUN dotnet publish "TC.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TC.dll"]
What is the current behavior?
In plain text:
47 #6 [build 2/9] RUN echo ""
48 #6 0.777
#11 [build 9/9] RUN cp -f /app/build/appsettings.json
#11 0.526 cp: missing destination file operand after "/app/build/appsettings.json
#11 0.526 Try 'cp --help' for more information.
#11 ERROR: process "/bin/sh -c cp -f $APPSETTINGS /app/build/appsettings.json" did not complete successfully: exit code: 1
-----
> [build 9/9] RUN cp -f /app/build/appsettings.json:
-----
process "/bin/sh -c cp -f $APPSETTINGS /app/build/appsettings.json" did,not complete successfully: exit code: 1
As you can see, the value of $APPSETTINGS
is empty inside the Dockerfile.
What is the expected behavior?
Value of $APPSETTINGS
should contain non-empty value, same as defined in GitLab CI/CD variables.
Relevant logs and/or screenshots
In GitLab:
Update variable:
- Key: "
APPSETTINGS
", - Value: "test",
- Type: "variable",
- environment scope: "staging",
- Flags: "Protect variable".