Skip to content

Commit

Permalink
Feature #521 develop sonarqube_gha (#525)
Browse files Browse the repository at this point in the history
* Per #521, add hooks for a SonarQube GHA workflow.

* Per #521, fix cut/paste error configure_sonarqube.sh

* Per #521, hard-code the Sonar Project key and name in the properties file since we're using the same project for all scans.

* Per #521, setup build_sonar.xml configuration by referencing environment variables.

* work in progress

* Per #521, move docker directory into internal/scripts for consistency across METplus repos

* Per #521, work in progress.

* Per #521, switch to running the sonar-scanner.

* Per #521, still working on the details

* Whitespace changes

* Per #521, try turning on the sonarqube workflow for this feature branch.

* Per #521, try turning on the sonarqube workflow for this feature branch.

* Per #521, try to save the logs

* Per #521, print the environment for debugging

* Per #521, define missing DOCKERHUB_REPO and SOURCE_BRANCH envvars

* Per #521, working on Dockerfile.copy

* Per #521, use hard-coded /METviewer directory instead of  to avoid inconsistent use of an environment variable.

* Per #521, METVIEWER_GIT_NAME is set as SOURCE_BRANCH rather than being a required envvar.

* Per #521, syntax

* Per #521, consistency of Dockerfiles.

* Per #521, remove feature_521_develop_sonarqube_gha branch name from sonarqube.xml I'd added to use for testing.

* Per #521, singularity is named apptainer, as of 2021

* Per #521, more work is needed in the DockerHub build hook. For now, switch to building against the develop version of the dependencies.
  • Loading branch information
JohnHalleyGotway authored Apr 22, 2024
1 parent 8770520 commit 75563bb
Show file tree
Hide file tree
Showing 18 changed files with 608 additions and 143 deletions.
34 changes: 34 additions & 0 deletions .github/jobs/bash_functions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#! /bin/bash

# utility function to run command get log the time it took to run
# if CMD_LOGFILE is set, send output to that file and unset var
function time_command {
local start_seconds=$SECONDS
echo "RUNNING: $*"

local error
# pipe output to log file if set
if [ "x$CMD_LOGFILE" == "x" ]; then
"$@"
error=$?
else
echo "Logging to ${CMD_LOGFILE}"
"$@" &>> $CMD_LOGFILE
error=$?
unset CMD_LOGFILE
fi

local duration=$(( SECONDS - start_seconds ))
echo "TIMING: Command took `printf '%02d' $(($duration / 60))`:`printf '%02d' $(($duration % 60))` (MM:SS): '$*'"
if [ ${error} -ne 0 ]; then
echo "ERROR: '$*' exited with status = ${error}"
fi
return $error
}

# utility function to construct the DockerHub tag name to be used,
# replacing slashes with underscores in the branch name

function get_dockerhub_tag {
echo ${DOCKERHUB_REPO}:$(echo ${SOURCE_BRANCH} | sed 's%/%_%g')
}
24 changes: 24 additions & 0 deletions .github/jobs/build_docker_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh

DOCKERHUB_TAG=$(get_dockerhub_tag)

DOCKERFILE_PATH=${GITHUB_WORKSPACE}/internal/scripts/docker/Dockerfile.copy

CMD_LOGFILE=${GITHUB_WORKSPACE}/docker_build.log

time_command docker build -t ${DOCKERHUB_TAG} \
--build-arg SOURCE_BRANCH \
--build-arg MET_BASE_REPO \
--build-arg MET_BASE_TAG \
-f $DOCKERFILE_PATH ${GITHUB_WORKSPACE}
if [ $? != 0 ]; then
cat ${CMD_LOGFILE}
exit 1
fi

# Copy the dist directory from the image
id=$(docker create ${DOCKERHUB_TAG})
time_command docker cp $id:/METviewer/dist dist
docker rm -v $id
62 changes: 62 additions & 0 deletions .github/jobs/configure_sonarqube.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/bash

# Constants
SONAR_PROPERTIES_DIR=internal/scripts/sonarqube
SONAR_PROPERTIES=sonar-project.properties

# Check that this is being run from the top-level METviewer directory
if [ ! -e $SONAR_PROPERTIES_DIR/$SONAR_PROPERTIES ]; then
echo "ERROR: ${0} -> must be run from the top-level METviewer directory"
exit 1
fi

# Check required environment variables
if [ -z ${SOURCE_BRANCH+x} ]; then
echo "ERROR: ${0} -> \$SOURCE_BRANCH not defined!"
exit 1
fi
if [ -z ${WD_REFERENCE_BRANCH+x} ]; then
echo "ERROR: ${0} -> \$WD_REFERENCE_BRANCH not defined!"
exit 1
fi
if [ -z ${SONAR_HOST_URL+x} ]; then
echo "ERROR: ${0} -> \$SONAR_HOST_URL not defined!"
exit 1
fi
if [ -z ${SONAR_TOKEN+x} ]; then
echo "ERROR: ${0} -> \$SONAR_TOKEN not defined!"
exit 1
fi

# Define the version string
export SONAR_PROJECT_VERSION=$(cat docs/version)

#
# Define the $SONAR_REFERENCE_BRANCH as the
# - Target of any requests
# - Manual setting for workflow dispatch
# - Source branch for any pushes (e.g. develop)
#
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
export SONAR_REFERENCE_BRANCH=$GITHUB_BASE_REF
elif [ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]; then
export SONAR_REFERENCE_BRANCH=$WD_REFERENCE_BRANCH
else
export SONAR_REFERENCE_BRANCH=$SOURCE_BRANCH
fi

# Configure the sonar-project.properties
[ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES
sed -e "s|SONAR_PROJECT_VERSION|$SONAR_PROJECT_VERSION|" \
-e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \
-e "s|SONAR_TOKEN|$SONAR_TOKEN|" \
-e "s|SONAR_BRANCH_NAME|$SOURCE_BRANCH|" \
$SONAR_PROPERTIES_DIR/$SONAR_PROPERTIES > $SONAR_PROPERTIES

# Define new code when the source and reference branches differ
if [ "$SOURCE_BRANCH" != "$SONAR_REFERENCE_BRANCH" ]; then
echo "sonar.newCode.referenceBranch=${SONAR_REFERENCE_BRANCH}" >> $SONAR_PROPERTIES
fi

echo "Contents of the $SONAR_PROPERTIES file:"
cat $SONAR_PROPERTIES
3 changes: 3 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
- [ ] Will this PR result in changes to the test suite? **[Yes or No]**</br>
If **yes**, describe the new output and/or changes to the existing output:</br>

- [ ] Do these changes introduce new SonarQube findings? **[Yes or No]**</br>
If **yes**, please describe:

- [ ] Please complete this pull request review by **[Fill in date]**.</br>

## Pull Request Checklist ##
Expand Down
99 changes: 99 additions & 0 deletions .github/workflows/sonarqube.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: SonarQube Scan

# Run SonarQube for Pull Requests and changes to the develop and main_vX.Y branches

on:

# Trigger analysis for pushes to develop and main_vX.Y branches
push:
branches:
- develop
- 'main_v**'
paths-ignore:
- 'docs/**'
- '.github/pull_request_template.md'
- '.github/ISSUE_TEMPLATE/**'
- '**/README.md'
- '**/LICENSE.md'

# Trigger analysis for pull requests to develop and main_vX.Y branches
pull_request:
types: [opened, synchronize, reopened]
branches:
- develop
- 'main_v**'
paths-ignore:
- 'docs/**'
- '.github/pull_request_template.md'
- '.github/ISSUE_TEMPLATE/**'
- '**/README.md'
- '**/LICENSE.md'

workflow_dispatch:
inputs:
reference_branch:
description: 'Reference Branch'
default: develop
type: string

env:
DOCKERHUB_REPO: dtcenter/metviewer-dev

jobs:
sonarqube:
name: SonarQube Scan
runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4
with:
# Disable shallow clones for better analysis
fetch-depth: 0

- name: Create output directories
run: mkdir -p ${RUNNER_WORKSPACE}/logs

- name: Get branch name
id: get_branch_name
run: echo branch_name=${GITHUB_REF#refs/heads/} >> $GITHUB_OUTPUT

- name: Build METviewer in Docker
run: .github/jobs/build_docker_image.sh
env:
SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }}

- name: Configure SonarQube
run: .github/jobs/configure_sonarqube.sh
env:
SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }}
WD_REFERENCE_BRANCH: ${{ github.event.inputs.reference_branch }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

- name: SonarQube Quality Gate check
id: sonarqube-quality-gate-check
uses: sonarsource/sonarqube-quality-gate-action@master
# Force to fail step after specific time.
timeout-minutes: 5
env:
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

- name: Copy log files into logs directory
if: always()
run: cp ${GITHUB_WORKSPACE}/*.log ${RUNNER_WORKSPACE}/logs/

- name: Upload logs as artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: logs_sonarqube
path: ${{ runner.workspace }}/logs
if-no-files-found: ignore
8 changes: 0 additions & 8 deletions docker/hooks/build

This file was deleted.

Loading

0 comments on commit 75563bb

Please sign in to comment.