How to build Docker image then use built image to run tests - azure-devops

I want to use Azure Pipelines to build a Docker image, then run tests inside the built image with a container job.
The image should use the build id as the tag (or a combination of the build id, commit hash and branch name). If I used a static tag as value (e.g. build), having two two pipelines run in parallell could result in an unwanted race condition.
The build step is easy enough - login, build and push to Docker Hub.
However, when specifying the test job to use a container, I'm unable to use a variable.
Here is an example that works, but it doesn't use a private registry.
variables:
- group: dockerCredentials
# contains: dockerUsername, dockerPassword
- name: imageName
value: azure-pipelines-test
- name: dockerRegistry
value: krsb
- name: fullImageName
value:
jobs:
- job: build
pool:
vmImage: 'Ubuntu-16.04'
steps:
- script: |
docker login -u $(dockerUsername) -p $(dockerPassword)
docker build -t '$(dockerRegistry)/$(imageName):$(build.buildId)' .
docker push '$(dockerRegistry)/$(imageName):$(build.buildId)'
displayName: 'docker build'
- job: test
dependsOn:
- build
pool:
vmImage: ubuntu-16.04
container:
image: $[ format('{0}/{1}:{2}', variables['dockerRegistry'], variables['imageName'], variables['build.buildId']) ]
endpoint: docker-hub-registry
steps:
- script: printenv
If I want to use a private registry, I don't specify container as a string, but use this syntax instead (Docker hub credentials is specified in the endpoint¹):
# ...
container:
image: image-name:tag
endpoint: docker-hub-registry
When I use this syntax, I cannot use the $[ variables['name'] ] syntax, this is not expanded and when the pipeline runs it outputs an error:
##[command]/usr/bin/docker pull $[ format('{0}:{1}', variables['imageName'], variables['build.buildId']) ]
"docker pull" requires exactly 1 argument.
Same goes if I use $(imageName):$(build.buildId).
Is it possible to use a variable in the image name?

Related

Invalid workflow file Github Actions (CF CLI)

I'm trying to get this github action to work but once committed it gives me this error:
Invalid workflow file: .github/workflows/main.yml#L1
No steps defined in steps and no workflow called in uses for the following jobs: build
Anyone have any idea what this might depend on?
Below is the code I used:
name: Deploy to Cloud Foundry
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-18.04
# Build your app here
deploy:
runs-on: ubuntu-18.04
needs: build
steps:
- uses: citizen-of-planet-earth/cf-cli-action#master
with:
cf_api: https://api.my-cloud-foundry.com
cf_username: ${{ secrets.CF_USER }}
cf_password: ${{ secrets.CF_PASSWORD }}
cf_org: AwesomeApp
cf_space: Development
command: push -f manifest-dev.yml
Thanks in advance to everyone
Following the Workflow Syntax for Github Actions, you'll identify that some fields are mandatory.
At the workflow level, you need to have at least a trigger (configure with the on field) and a list of jobs specified.
Then, in that list of jobs, you have to specify at least one job, where each of those jobs needs at least the runner and the steps (or the uses for reusable workflow) field configured.
Example of the minimum configurations you would use for a job:
on: push
jobs:
job1:
runs-on: ubuntu-latest
steps:
- name: Print a greeting
run: echo 'Hello World'
job2: # reusable workflow scenario
uses: owner/repo/.github/workflows/reusable-workflow.yml#main

Combine variables in Azure Devops Build Pipeline YAML

I'm creating a docker build and push task in an Azure Devops Build pipeline YAML file, and I'd like to tag the image with the combination of two variables, the project name and the build number, so the tag would be service_22 (service is the project, 22 is the build number).
How do I join two variables together, e.g. $(variable)_$(variable2)
- task: Docker#2
inputs:
containerRegistry: 'Azure'
repository: 'jdmcontainers'
command: 'buildAndPush'
Dockerfile: 'Dockerfile'
tags: |
$(Build.BuildId)
$(imageName)
That's the current file, the tags are added as individual separate tags.
For those who come here and are actually looking for a way to combine two strings/variables in the job variable declaration, you can use the format() expression (docs link):
- job: Build
variables:
job_variable: $[format('Hey-{0}', variables['Build.Reason'])]
Hope that helps someone, at leased I searched for this for hours and found nothing. ^^
Try with below format:
steps:
- task: Docker#2
displayName: buildAndPush
inputs:
xxxx
tags: '$(System.TeamProject)_$(Build.Buildid)'
$(System.TeamProject) is one environment variable which can get the current project name.
Try this it works in Azure pipeline yaml
parameters:
- name: String1
displayName: StringName
type: string
values: 'Hello '
variables:
- name: String2
value: 'World'
- name: StringConcat
value: ${{parameters.String1}}${{variables.String2}}

Gitlab yaml to azure pipelines yaml file

I'm trying to convert but after reading some sources im not sure how I can convert this part of yaml code that works with gitlab CI to azure pipelines yaml:
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist
only:
- master
deploy:
stage: deploy
script:
- npm i -g netlify-cli
- netlify deploy --site $NETLIFY_SITE_ID --auth $NETLIFY_AUTH_TOKEN --prod
dependencies:
- build
only:
- master
Especially I want to set the artifact path in the build stage and then somehow set that in the deploy stage.
Here how it looks now in my azure-pipelines yaml:
- script: |
npm run build
displayName: 'Build'
- script: |
npm i -g netlify-cli
netlify deploy --site $NETLIFY_SITE_ID --auth $NETLIFY_AUTH_TOKEN --prod
displayName: 'Deploy'
See below sample:
variables:
- name: netlify.site.id
value: {value}
- name: netlify.auth.token
value: {token}
trigger:
- master
pool:
vmImage: 'vs2017-win2016'
stages:
- stage: Build
jobs:
- job: ARM
steps:
- script: npm -version
- publish: $(System.DefaultWorkingDirectory)
artifact: dist
- stage: Deploy
dependsOn: Build
condition: succeeded()
jobs:
- job: APP
steps:
- bash: |
npm i -g netlify-cli
netlify deploy --site $(netlify.site.id) --auth $(netlify.auth.token) --prod
Tip1: If the value of netlify.auth.token and netlify.site.id is very private for you, and you do not want it public in YAML. You can store them in variable group. And then change the Variables part as:
variables:
- group: {group name}
See this doc.
Tip2: For the stage dependency, you can use dependsOn keyword in VSTS yaml to achieve the dependency. See this.
Tip3: In VSTS, you must specify stages, jobs and steps which used as the entry point for the server to compile the respective part.
A stage is a collection of related jobs.
A job is a collection of steps to be run by an agent or on the
server.
Steps are a linear sequence of operations that make up a job.
Tip4: To achieve publishing artifacts in VSTS with YAML, there has 2 different format. One is what I show for you above. The publish keyword is a shortcut for the Publish Pipeline Artifact task.
Another one format, see this Publishing artifacts

How to get matrix's job's name in the steps part of the yaml file?

I have a pretty simple Azure Pipelines YAML file like:
pool:
vmImage: 'ubuntu-18.04'
strategy:
matrix:
debian:
img: 'debian:latest'
fedora:
img: 'fedora:latest'
arch:
img: 'archlinux:latest'
opensuse:
img: 'opensuse/leap:latest'
container: $[ variables['img'] ]
steps:
- script: printenv
displayName: Dump env
- script: make
displayName: Build the project
Which does nothing more than building the same project on each of the four containers enlisted above.
It works, but I'd like to have also a step that uses the name of the job (debian, fedora, etc.) for running a special script.
How can I get access to the job's name in steps? Is there something like $(job)?
You have the pre-defined variable $(Agent.JobName) that you can use. for example:
steps:
- script: echo $(Agent.JobName))
displayName: echo $(Agent.JobName))
Will give this output:

How to have conditional image tags on azure devops build yaml pipeline?

For several environments, I need to have different docker image tagging policies, that is: dev and release should utilize 'Latest' tag, while production should have proper version tag.
I am currently using single Yaml file for all AzureDevOps Build Pipeline, and want to have image tagging mode to be defined as Variable per build /lets say called $(Versioned)/.
The build step is shown below:
steps
- bash: docker push $(imageFullName):latest
displayName: 'docker push'
So is there any way to have IF statement or other conditional operation here.
For example:
steps
- bash: docker push $(imageFullName):IF($(Versioned), $(Build.BuildNumber), latest)
displayName: 'docker push'
you can maybe do this with something like this:
steps
- bash: docker push $(imageFullName):latest
displayName: 'docker push'
condition: eq($(Versioned), 'true')
- bash: docker push $(imageFullName):$(Build.BuildNumber)
displayName: 'docker push'
condition: ne($(Versioned), 'true')