Skip to content

chore(jenkins): Update Jenkins plugins (#366) #397

chore(jenkins): Update Jenkins plugins (#366)

chore(jenkins): Update Jenkins plugins (#366) #397

Workflow file for this run

# This workflow is used to test the docker-compose files for the default, maven, python, and node directories.
name: docker-compose files test
on:
push:
branches:
- '*' # The workflow will run on push events on all branches.
jobs:
# This job builds and tests the docker-compose files for the maven, python, and node directories.
build-and-test:
strategy:
matrix:
dir: [maven, python, node] # The directories to be tested.
runs-on: ubuntu-latest # The type of machine to run the job on.
timeout-minutes: 30
# Set environment variables for the github username for using the forked repo for tutorials (currently using mine)
env:
GITHUB_USERNAME: gounthar # Used to be ${{ github.repository_owner }}, but the jenkins-docs repository does not have a Jenkinsfile.
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
IMAGE_PREFIX: ghcr.io
BRANCH_SUFFIX: clean-up
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for all branches and tags.
# Set the repository URL based on the directory specified in the matrix.
- name: Set Sample Tutorial Repository URL
run: |
if [[ "${{ matrix.dir }}" == "maven" ]]; then
# The line is storing the URL of the GitHub repository for the simple-java-maven-app in an environment variable named PARTIAL_REPO_URL.
# The ${GITHUB_USERNAME} is a placeholder that will be replaced with the value of the GITHUB_USERNAME environment variable, which is set to the owner of the repository.
echo "PARTIAL_REPO_URL=${GITHUB_USERNAME}/simple-java-maven-app" >> $GITHUB_ENV
elif [[ "${{ matrix.dir }}" == "python" ]]; then
echo "PARTIAL_REPO_URL=${GITHUB_USERNAME}/simple-python-pyinstaller-app" >> $GITHUB_ENV
elif [[ "${{ matrix.dir }}" == "node" ]]; then
echo "PARTIAL_REPO_URL=${GITHUB_USERNAME}/simple-node-js-react-npm-app" >> $GITHUB_ENV
fi
echo "GITHUB_ENV is $GITHUB_ENV"
echo "REPO_URL is $REPO_URL"
shell: bash
- name: Extract current branch name
shell: bash
run: |
BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | sed -e 's#/#-#g')
if [[ "$BRANCH_NAME" == "main" ]]; then BRANCH_NAME=""; fi
echo "BRANCH=$BRANCH_NAME" >> $GITHUB_ENV
id: extract_branch
- name: Extract the current branch name and set the BRANCH environment variable
shell: bash
run: |
BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | sed -e 's#/#-#g')
if [[ "$BRANCH_NAME" == "main" ]]; then BRANCH_NAME=""; fi
echo "BRANCH=$BRANCH_NAME" >> $GITHUB_ENV
- name: Print Sample Tutorial REPO_URL
run: echo "The repository URL is ${{ env.PARTIAL_REPO_URL }}"
# Create a config.xml file in the dockerfiles/jobs directory to add the test job to the instance.
- name: Create config.xml for the Sample Tutorial job
env:
BRANCH_SUFFIX: ${{ env.BRANCH }}
# Full repo URL
REPO_URL: "https://github.com/${{ env.PARTIAL_REPO_URL }}.git"
run: |
# adding test job to the tutorial with REPO_URL
# The XML content is a Jenkins job configuration in XML format.
# It defines a pipeline job that checks out the specified repository and runs the Jenkinsfile in it.
XML_CONTENT=$(cat <<EOL
<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job@1316.vd2290d3341a_f">
<actions>
<org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobAction plugin="pipeline-model-definition@2.2144.v077a_d1928a_40"/>
<org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction plugin="pipeline-model-definition@2.2144.v077a_d1928a_40">
<jobProperties/>
<triggers/>
<parameters/>
<options/>
</org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction>
</actions>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition" plugin="workflow-cps@3722.v85ce2a_c6240b_">
<scm class="hudson.plugins.git.GitSCM" plugin="git@5.2.0">
<configVersion>2</configVersion>
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>${REPO_URL}</url>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>*/master</name>
</hudson.plugins.git.BranchSpec>
</branches>
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
<submoduleCfg class="empty-list"/>
<extensions/>
</scm>
<scriptPath>Jenkinsfile</scriptPath>
<lightweight>true</lightweight>
</definition>
<triggers/>
<disabled>false</disabled>
</flow-definition>
EOL
)
echo "pwd is $(pwd)"
echo "$XML_CONTENT" > ./config.xml
echo "checking files below"
tree .
# Check if any files in the specified directory have changed and run docker-compose up with the directory as an argument if there are changes.
- name: checking files & running the docker compose up with ${{ matrix.dir }} argument
run: |
if [ $(git diff --name-only HEAD^ HEAD | uniq | grep -c "${{ matrix.dir }}") -ne 0 ]; then
echo "Changed directories are $(git diff --name-only HEAD^ HEAD | uniq)"
docker compose -f build-docker-compose.yaml --profile ${{ matrix.dir }} up -d --build # Run docker-compose up with the directory as an argument.
else
echo "No Internal examples were modified"
echo 'NO_CHANGES=true' >> $GITHUB_ENV
fi
# Wait for services to be ready if there were changes in the specified directory.
- name: Waiting for services to be ready
if: env.NO_CHANGES != 'true'
run: |
# After the curl request, the output is piped to the awk command. It is used to search for the message
# "Please wait while Jenkins is getting ready to work" in the curl output.
# If the message is found, awk exits with a non-zero status (1), and the loop continues.
# If the message is not found, the loop exits, and the "Jenkins is running" message is displayed.
timeout 60 bash -c 'until curl -s -f http://127.0.0.1:8080/login > /dev/null; do sleep 5; done' && echo "Jenkins is running" || echo "Jenkins is not running"
echo "Jenkins is ready"
JENKINS_VERSION=$(curl -s -I -k http://admin:admin@127.0.0.1:8080 | grep -i '^X-Jenkins:' | awk '{print $2}')
echo "Jenkins version is: $JENKINS_VERSION"
# Test The stack
- name: Run curl command to test the stack
if: env.NO_CHANGES != 'true'
run: |
# The following steps are used to test the Jenkins stack.
# It includes steps to install dependencies, create a token for the admin user, launch a job, wait for the job to start running,
# wait for the job to complete, and check the job status.
# If the job fails, it gives the console output of why it failed and exits with a non-zero status to fail the step and stop the workflow.
# If the job succeeds, it prints "Job succeeded".
# The detailed steps are documented in the comments within the code block.
set -x
# Installing dependencies
# To check the version of Jenkins, load the top page or any .../api/* page and check for the X-Jenkins response header. This contains the version number of Jenkins, like "1.404" This is also a good way to check if an URL is a Jenkins URL.
JENKINS_VERSION=$(curl -s -I -k http://admin:admin@127.0.0.1:8080 | grep -i '^X-Jenkins:' | awk '{print $2}')
echo "Jenkins version is: $JENKINS_VERSION"
# Before launching a job, we need to create a token for the admin user
CRUMB=$(curl -s -k http://admin:admin@127.0.0.1:8080/crumbIssuer/api/xml?xpath=concat\(//crumbRequestField,%22:%22,//crumb\) -c cookies.txt)
echo "CRUMB was found."
TOKEN=$(curl -s -k 'http://admin:admin@127.0.0.1:8080/user/admin/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken' --data 'newTokenName=kb-token' -b cookies.txt -H $CRUMB | jq -r '.data.tokenValue')
echo "TOKEN was found."
# Creating the Job from the config.xml file
curl -X POST -H "Content-Type: text/xml" --user admin:$TOKEN --data-binary @config.xml http://127.0.0.1:8080/createItem?name=${{ matrix.dir }}
# Let's set the JOB_NAME it's same as the running tutorial (i.e. maven, python, node)
JOB_NAME="${{ matrix.dir }}"
echo "Launching a job whose name is $JOB_NAME (unencoded)"
# Encode the JOB_NAME to replace spaces, open parentheses, and closing parentheses with their corresponding URL-encoded values.
# This is necessary when using the JOB_NAME in a URL or any other context where special characters need to be encoded.
# Spaces are replaced with "%20", open parentheses with "%28", and closing parentheses with "%29".
# The encoded result is stored in the JOB_NAME_ENCODED variable. This step was useful with using (simple demo job)
JOB_NAME_ENCODED=$(echo "$JOB_NAME" | awk '{ gsub(/ /, "%20"); gsub(/\(/, "%28"); gsub(/\)/, "%29"); print }')
echo "JOB_NAME_ENCODED is $JOB_NAME_ENCODED"
# Checking the present job, debug step, checks if the test job is present.
JOB_PRESENT=$(curl -u admin:$TOKEN http://127.0.0.1:8080/api/json?tree=jobs%5Bname%5D)
echo "JOB_PRESENT is $JOB_PRESENT"
# Starting the job, TOKEN has been set in the previous step
curl -X POST -u admin:$TOKEN 127.0.0.1:8080/job/$JOB_NAME_ENCODED/build
# Wait for the job to start running
sleep 10
echo "Waiting for the job to start running..."
BUILD_NUMBER="null"
# While loop checks if BUILD__NUMBER is empty or null, breaks otherwise
while [[ -z $BUILD_NUMBER || $BUILD_NUMBER == "null" ]]; do
# Retrieve build info from Jenkins API using cURL
BUILD_INFO=$(curl -s -k http://admin:$TOKEN@127.0.0.1:8080/job/$JOB_NAME_ENCODED/api/json)
echo "Retrieved build info: $BUILD_INFO"
# Extract the build number from the JSON response using jq
BUILD_NUMBER=$(echo $BUILD_INFO | jq -r '.lastBuild.number')
# Check if the build is in progress
BUILD_IN_PROGRESS=$(echo $BUILD_INFO | jq -r '.lastBuild.building')
echo "Build number: $BUILD_NUMBER"
echo "Build in progress: $BUILD_IN_PROGRESS"
# If the build number is not empty and the build is in progress, break out of the loop
if [[ -n $BUILD_NUMBER && $BUILD_IN_PROGRESS == "true" ]]; then
break
fi
# Sleep for 5 seconds before checking the build status again
sleep 15 # Adjust the sleep duration as needed
done
echo "This is BUILD__NUMBER $BUILD_NUMBER"
# Delay before retrieving build information
sleep 15
if [[ -z $BUILD_NUMBER ]]; then
# If the build number is empty or "null", it means the job has never run
echo "Job has never run"
else
# If the build number is not empty, the job has started and the build number is displayed
echo "Job started. Build number: $BUILD_NUMBER"
fi
# Wait for the job to complete
echo "Waiting for the job to complete..."
while true; do
# Retrieve the build status and whether the build is in progress
BUILD_STATUS=$(curl -s -k http://admin:$TOKEN@127.0.0.1:8080/job/$JOB_NAME_ENCODED/$BUILD_NUMBER/api/json | jq -r '.result')
BUILD_IN_PROGRESS=$(curl -s -k http://admin:$TOKEN@127.0.0.1:8080/job/$JOB_NAME_ENCODED/$BUILD_NUMBER/api/json | jq -r '.building')
echo "Build status: $BUILD_STATUS"
echo "Build in progress: $BUILD_IN_PROGRESS"
# If the build status is not "null", it means the build has been completed
if [[ $BUILD_STATUS != "null" ]]; then
break
fi
# Below step is for the node tutorial only, in which we need to give input (click PROCEED) in order to complete the pipeline
curl -s -k -X POST -u admin:$TOKEN http://127.0.0.1:8080/job/$JOB_NAME_ENCODED/$BUILD_NUMBER/input/PROCEED/proceedEmpty
sleep 5 # Adjust the sleep duration as needed
done
# Checks BUILD_STATUS to see if job succeeded or failed and if failed gives console output of why it failed and exit
if [[ $BUILD_STATUS == "SUCCESS" ]]; then
echo "Job succeeded"
else
echo "Job failed"
echo "below is the console output"
echo "====================="
curl -s -k -u admin:$TOKEN http://127.0.0.1:8080/job/$JOB_NAME/$BUILD_NUMBER/console
exit 1 # Exit with a non-zero status to fail the step and stop the workflow
fi
- name: Teardown
if: env.NO_CHANGES != 'true'
run: docker compose down
build-and-test-default:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up and start Docker Compose
run: |
docker compose --profile default up -d
echo "Docker Compose started"
- name: Waiting for services to be ready
run: |
# After the curl request, the output is piped to the awk command. It is used to search for the message
# "Please wait while Jenkins is getting ready to work" in the curl output.
# If the message is found, awk exits with a non-zero status (1), and the loop continues.
# If the message is not found, the loop exits, and the "Jenkins is running" message is displayed.
timeout 60 bash -c 'until curl -s -f http://127.0.0.1:8080/login > /dev/null; do sleep 5; done' && echo "Jenkins is running" || echo "Jenkins is not running"
echo "Jenkins is ready"
JENKINS_VERSION=$(curl -s -I -k http://admin:admin@127.0.0.1:8080 | grep -i '^X-Jenkins:' | awk '{print $2}')
echo "Jenkins version is: $JENKINS_VERSION"
- name: Run curl command to test the stack
run: |
set -x
# Installing dependencies
# To check Sthe version of Jenkins, load the top page or any .../api/* page and check for the X-Jenkins response header. This contains the version number of Jenkins, like "1.404" This is also a good way to check if an URL is a Jenkins URL.
JENKINS_VERSION=$(curl -s -I -k http://admin:admin@127.0.0.1:8080 | grep -i '^X-Jenkins:' | awk '{print $2}')
echo "Jenkins version is: $JENKINS_VERSION"
# Before launching a job, we need to create a token for the admin user
CRUMB=$(curl -s -k http://admin:admin@127.0.0.1:8080/crumbIssuer/api/xml?xpath=concat\(//crumbRequestField,%22:%22,//crumb\) -c cookies.txt)
echo "CRUMB was found."
TOKEN=$(curl -s -k 'http://admin:admin@127.0.0.1:8080/user/admin/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken' --data 'newTokenName=kb-token' -b cookies.txt -H $CRUMB | jq -r '.data.tokenValue')
echo "TOKEN was found."
# Let's set the JOB_NAME it's same as the running tutorial (i.e. maven, python, node)
echo "Launching a job"
JOB_NAME="%28simple%29%20demo%20job"
# Encode the JOB_NAME to replace spaces, open parentheses, and closing parentheses with their corresponding URL-encoded values.
# This is necessary when using the JOB_NAME in a URL or any other context where special characters need to be encoded.
# Spaces are replaced with "%20", open parentheses with "%28", and closing parentheses with "%29".
# The encoded result is stored in the JOB_NAME_ENCODED variable. This step was usefull with using (simple demo job)
JOB_NAME_ENCODED=$(echo "$JOB_NAME" | awk '{ gsub(/ /, "%20"); gsub(/\(/, "%28"); gsub(/\)/, "%29"); print }')
echo "JOB_NAME_ENCODED is $JOB_NAME_ENCODED"
# Checking the present job, debug step, checks if the test job is present.
JOB_PRESENT=$(curl -u admin:$TOKEN http://127.0.0.1:8080/api/json?tree=jobs%5Bname%5D)
echo "JOB_PRESENT is $JOB_PRESENT"
#Staring the job, TOKEN has been set in previous step
curl -X POST -u admin:$TOKEN 127.0.0.1:8080/job/$JOB_NAME_ENCODED/build
# Wait for the job to start running
sleep 10
echo "Waiting for the job to start running..."
BUILD_NUMBER="null"
# While loop checks if BUILD__NUMBER is empty or null, breaks otherwise
while [[ -z $BUILD_NUMBER || $BUILD_NUMBER == "null" ]]; do
# Retrieve build info from Jenkins API using cURL
BUILD_INFO=$(curl -s -k http://admin:$TOKEN@127.0.0.1:8080/job/$JOB_NAME_ENCODED/api/json)
echo "Retrieved build info: $BUILD_INFO"
# Extract the build number from the JSON response using jq
BUILD_NUMBER=$(echo $BUILD_INFO | jq -r '.lastBuild.number')
# Check if the build is in progress
BUILD_IN_PROGRESS=$(echo $BUILD_INFO | jq -r '.lastBuild.building')
echo "Build number: $BUILD_NUMBER"
echo "Build in progress: $BUILD_IN_PROGRESS"
# If the build number is not empty and the build is in progress, break out of the loop
if [[ -n $BUILD_NUMBER && $BUILD_IN_PROGRESS == "true" ]]; then
break
fi
# Sleep for 5 seconds before checking the build status again
sleep 15 # Adjust the sleep duration as needed
done
echo "This is BUILD__NUMBER $BUILD_NUMBER"
# Delay before retrieving build information
sleep 15
if [[ -z $BUILD_NUMBER ]]; then
# If the build number is empty or "null", it means the job has never run
echo "Job has never run"
else
# If the build number is not empty, the job has started and the build number is displayed
echo "Job started. Build number: $BUILD_NUMBER"
fi
# Wait for the job to complete
echo "Waiting for the job to complete..."
while true; do
# Retrieve the build status and whether the build is in progress
BUILD_STATUS=$(curl -s -k http://admin:$TOKEN@127.0.0.1:8080/job/$JOB_NAME_ENCODED/$BUILD_NUMBER/api/json | jq -r '.result')
BUILD_IN_PROGRESS=$(curl -s -k http://admin:$TOKEN@127.0.0.1:8080/job/$JOB_NAME_ENCODED/$BUILD_NUMBER/api/json | jq -r '.building')
echo "Build status: $BUILD_STATUS"
echo "Build in progress: $BUILD_IN_PROGRESS"
# If the build status is not "null", it means the build has been completed
if [[ $BUILD_STATUS != "null" ]]; then
break
fi
sleep 5 # Adjust the sleep duration as needed
done
# Checks BUILD_STATUS to see if job succeeded or failed and if failed gives console output of why it failed and exit
if [[ $BUILD_STATUS == "SUCCESS" ]]; then
echo "Job succeeded"
else
echo "Job failed"
echo "below is the console output"
echo "====================="
curl -s -k -u admin:$TOKEN http://127.0.0.1:8080/job/$JOB_NAME/$BUILD_NUMBER/console
exit 1 # Exit with a non-zero status to fail the step and stop the workflow
fi
- name: Teardown
run: |
docker compose down