How to get or parse coverage persentage of Jacoco report in GitHub Actions - build.gradle

I have Spring Boot app it uses gradle for build and package. I have configured Jacoco plugin and generating report in my local as HTML. I want to include it in my GitHub build workflow so whenever build runs I want to upload/store that Jacoco generated html report in the branch in which build is running. Is it possible using GitHub Actions?
Also once Jacoco build report is created want to extract final code coverage percentage of that build (this percentage is only for my defined coverage rule) and create a badge in the repository in which build is running.
EDIT
test {
finalizedBy jacocoTestReport // report is always generated after tests run
}
jacocoTestReport {
dependsOn test // tests are required to run before generating the report
}
jacoco {
toolVersion = "0.8.6"
//reportsDirectory = file("$buildDir/report/")
}
jacocoTestReport {
dependsOn test
sourceSets sourceSets.main
executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")
reports {
xml.enabled false
csv.enabled true
html.destination file("${buildDir}/reports/jacoco/Html")
csv.destination file("${buildDir}/reports/jacoco/jacoco.csv")
}
}
//Test coverage Rule to make sure code coverage is 100 %
jacocoTestCoverageVerification {
violationRules {
rule {
element = 'CLASS'
limit {
counter = 'LINE'
value = 'COVEREDRATIO'
minimum = 1.0
}
excludes = [
'com.cicd.herokuautodeploy.model.*',
'com.cicd.herokuautodeploy.HerokuautodeployApplication',
'com.cicd.herokuautodeploy.it.*'
]
}
}
}
WorkFlow File
# This workflow will build a Java project with Gradle whenever Pull and Merge request to main branch
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Build WorkFlow - Building and Validating Test Coverage
on:
pull_request:
branches: [ main,dev ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Set up JDK 1.11
uses: actions/setup-java#v1
with:
java-version: 1.11
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
- name: Generate JaCoCo Badge
id: jacoco
uses: cicirello/jacoco-badge-generator#v2.0.1
- name: Log coverage percentage
run: |
echo "coverage = ${{ steps.jacoco.outputs.coverage }}"
echo "branch coverage = ${{ steps.jacoco.outputs.branches }}"
- name: Commit the badge (if it changed)
run: |
if [[ `git status --porcelain` ]]; then
git config --global user.name 'UserName'
git config --global user.email 'useremail#gmail.com'
git add -A
git commit -m "Autogenerated JaCoCo coverage badge"
git push
fi
- name: Upload JaCoCo coverage report
uses: actions/upload-artifact#v2
with:
name: jacoco-report
path: reports/jacoco/
Error
File "/JacocoBadgeGenerator.py", line 88, in computeCoverage
with open(filename, newline='') as csvfile :
FileNotFoundError: [Errno 2] No such file or directory: 'target/site/jacoco/jacoco.csv'

Disclosure: I am the author of the cicirello/jacoco-badge-generator GitHub Action that this question concerns.
Although the default behavior assumes Maven's location of the jacoco.csv, there is an action input that can be used to indicate the location of the jacoco report. So in your case, with gradle, you can change the cicirello/jacoco-badge-generator step of your workflow to the following (if you use gradle's default location and filename for the report):
- name: Generate JaCoCo Badge
uses: cicirello/jacoco-badge-generator#v2
with:
jacoco-csv-file: build/reports/jacoco/test/jacocoTestReport.csv
It looks like your gradle configuration changed the report location though, so you will need the following in order to coincide with your report location and filename:
- name: Generate JaCoCo Badge
id: jacoco
uses: cicirello/jacoco-badge-generator#v2
with:
jacoco-csv-file: build/reports/jacoco/jacoco.csv
The id: jacoco is just because one of your later steps in your workflow is referring to the action outputs through that id.

If you can configure jacoco to generate a jacoco.csv file, then the GitHub Action jacoco-badge-generator can generate the requested badge.
See for instance "Use Jacoco And GitHub Actions to Improve Code Coverage" from Rodrigo Graciano for an example of pom.xml project configuration to generate the report during build.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
For a gradle example:
jacocoTestReport {
dependsOn test
sourceSets sourceSets.main
executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")
reports {
xml.enabled false
csv.enabled true
html.destination file("${buildDir}/reports/jacoco/Html")
csv.destination file("${buildDir}/reports/jacoco/jacoco.csv")
}
}

Related

Git Hub Actions Error - fatal: not a git repository (or any of the parent directories): .git

I am new to GitHub Actions and I am just trying to use the 'Test Reporter' action in my workflow.
These are my steps:
- name: Test
env:
SERVER_PATH: ${{ github.workspace }}/drop/${{ env.PATH}}
run: mvn --batch-mode -Dmaven.test.failure.ignore=true test --file ${{ env.PATH }}/pom.xml
- name: Test Report
env:
SERVER_PATH: ${{ github.workspace }}/drop/${{ env.PATH}}
uses: dorny/test-reporter#v1
if: always()
with:
name: Maven Tests
path: target/surefire-reports/*.xml
reporter: java-junit
fail-on-error: true`
The test step works as expected, I am only getting an error in the test report step.
Error:
Check runs will be created with
SHA=589c5f9c5b663f851f3f9bd49fbc66a00634183c
Listing all files tracked by git
/usr/bin/git ls-files -z
fatal: not a git repository (or any of the parent directories): .git
Error: Error: The process '/usr/bin/git' failed with exit code 128
Please help!
Update: Feb 6, 2023:
Test Report
Run dorny/test-reporter#v1
with:
name: Maven Tests
path: target/surefire-reports/*.xml
reporter: java-junit
fail-on-error: true
path-replace-backslashes: false
list-suites: all
list-tests: all
max-annotations: 10
only-summary: false
token: ***
env:
APPCONFIGRGP: appconfig
APPCONFIGSKU: Standard
BACKENDPATH: MyApp
JAVA_HOME_8.0.362_x64: /home/azureuser/actions-runner/_work/_tool/jdk/8.0.362/x64
JAVA_HOME: /home/azureuser/actions-runner/_work/_tool/jdk/8.0.362/x64
JAVA_HOME_8_0_362_X64: /home/azureuser/actions-runner/_work/_tool/jdk/8.0.362/x64
SERVER_PATH: /home/azureuser/actions-runner/_work/App/App/temp/App
Check runs will be created with SHA=05410264d739b3ccb57fe740d230cd4b428ef605
Listing all files tracked by git
/usr/bin/git ls-files -z
fatal: not a git repository (or any of the parent directories): .git
Error: Error: The process '/usr/bin/git' failed with exit code 128

GitHub dependabot for a library inside a yml file

Introduction
I'm currently working on a project that automatically containerizes a java project with JIB.
GitHub project link.
Problem
The LIB library is implicitly used inside the YAML file, like this :
- name: Build JIB container and publish to GitHub Packages
run: |
if [ ! -z "${{ inputs.module }}" ]; then
MULTI_MODULE_ARGS="-am -pl ${{ inputs.module }}"
fi
if [ ! -z "${{ inputs.main-class }}" ]; then
MAIN_CLASS_ARGS="-Djib.container.mainClass=${{ inputs.main-class }}"
fi
mvn package com.google.cloud.tools:jib-maven-plugin:3.2.1:build \
-Djib.to.image=${{ inputs.REGISTRY }}/${{ steps.downcase.outputs.lowercase }}:${{ inputs.tag-name }} \
-Djib.to.auth.username=${{ inputs.USERNAME }} \
-Djib.to.auth.password=${{ inputs.PASSWORD }} $MULTI_MODULE_ARGS $MAIN_CLASS_ARGS
shell: bash
When the new version of JIB is released my dependabot configuration doesn't update the YAML file.
Configuration of the Dependabot :
version: 2
updates:
- package-ecosystem: github-actions
directory: '/'
schedule:
interval: weekly
Question
Does someone know how to configure dependabot.yml for an implicitly declared library?
Or how to configure Dependabot.yml to automatically create an issue when a new JIB version is released?
You can do it with hiden-dependency-updater
Example of GitHub Workflow you can use:
name: Update hidden dependencies
on:
schedule:
- cron: '0 0 * * *'
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- uses: MathieuSoysal/hiden-dependency-updater#v1.1.1
with:
files: action.yml # List of files to update
prefix: "com.google.cloud.tools:jib-maven-plugin:" # Prefix before the version, default is: ""
suffix: ":build ."
regex: "[0-9.]*"
selector: "maven"
github_repository: "GoogleContainerTools/jib"
- name: Create Pull Request
uses: peter-evans/create-pull-request#v4
with:
token: ${{ secrets.GITHUB_TOKEN }} # You need to create your own token with pull request rights
commit-message: update jib
title: Update jib
body: Update jib to reflect release changes
branch: update-jib
base: main
From the doc:
The directory must be set to "/" to check for workflow files in
.github/workflows.
- package-ecosystem: "github-actions"
# Workflow files stored in the
# default location of `.github/workflows`
directory: "/"
schedule:
interval: "daily"
So: try specifying a different directory, as example:
- package-ecosystem: "github-actions"
# Workflow files stored in the
directory: "."
schedule:
interval: "daily"

How to deploy private repository as packages

I am using Enterprise Git 3.0, created a private repository.
I created a GitHub Personal Access Token, stored it in the repository's secret and referred it from the workflow. The PAT has rights to read/write packages.
I created the workflow action mentioned below, but whenever I run, it's giving 401: Unauthorized.
Can someone guide me on what is missing.
name: Git Deploy
on:
push:
jobs:
publish:
strategy:
matrix:
maven: [ '3.6.3' ]
runs-on: [ self-hosted ]
steps:
- uses: actions/checkout#v2
- name: Set up JDK 1.8
uses: actions/setup-java#v1
with:
java-version: 1.8
server-id: github2 # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- name: install maven # If I don't do this, I was getting mvn not found error
uses: stCarolas/setup-maven#v4.2
with:
maven-version: 3.6.3
- name: read secrets from settings
uses: s4u/maven-settings-action#v2.5.0
with:
servers: |
[{
"id": "github2",
"username": "my github user id (Not email)",
"password": "${{ secrets.PAT }}"
}]
- name: Build and deploy
run: mvn -B deploy
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
GITHUB_USER: "my github user id (Not email)"
Link I am referring
https://docs.github.com/en/actions/publishing-packages/publishing-java-packages-with-maven

How to reference proper directory in a github actions workflows to call a module

I'm running my workflows using GitHub Actions. When I create a pull_request that will trigger my workflow, I am getting the error message at the bottom of my question. What I am trying to do is to call my infrastructure/test/main.tf from my audit-account/prod-env directory. What do i need to change in the Env section for directory
# deploy.yml
name: 'GitHub OIDC workflow'
on:
pull_request:
branches:
- prod
env:
tf_version: 'latest'
tg_version: 'latest'
tf_working_dir: './audit-account/prod-env'
permissions:
id-token: write
contents: read
jobs:
deploy:
name: 'Build and Deploy'
runs-on: ubuntu-latest
steps:
- name: 'checkout'
uses: actions/checkout#v2
- name: configure AWS credentials
uses: aws-actions/configure-aws-credentials#master
with:
aws-region: us-east-1
role-to-assume: arn:aws:iam::123456789012:role/GitHubActions_Workflow_role
role-duration-seconds: 3600
- name: 'Terragrunt Init'
uses: the-commons-project/terragrunt-github-actions#master
with:
tf_actions_version: ${{ env.tf_version }}
tg_actions_version: ${{ env.tg_version }}
tf_actions_subcommand: 'init'
tf_actions_working_dir: ${{ env.tf_working_dir }}
tf_actions_comment: true
env:
TF_INPUT: false
# audit-account/prod-env/terragrunt.hcl
terraform {
source = "../../../../..//infrastructure/test"
}
include {
path = find_in_parent_folders()
}
infrastructure/test
main.tf
resource "aws_vpc" "test-vpc" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
tags = {
Name = "OIDC"
}
}
error message:
init: info: initializing Terragrunt configuration in /audit-account/prod-env
init: error: failed to initialize Terragrunt configuration in /audit-account/prod-env
time=2021-11-17T23:55:54Z level=error msg=Working dir infrastructure/test from source file:///github/workspace/audit-account/prod-env does not exist
Your source path for the infrastructure module goes way too far up in the folder structure.
Assuming you have the infrastructure and audit-account directories at the root of the repository, your source would be ../../infrastructure/test. You have it looking 5 folders up from audit-account/prod-env, which puts you 3 folders above the workspace in a folder somewhere on the runner's filesystem.

Use dynamic input value for Environment in GitHub Actions workflow job

I'm trying to make a GitHub Actions workflow where one job has a dynamic value to its environment setting. https://docs.github.com/en/actions/reference/environments I have two jobs in this workflow. The first job determines which environment the second job will run in, and this is in turn based on which git branch the Actions job is run from.
This is my naive attempt to make it work, but I get an error which says
(Line: 29, Col: 18): Unrecognized named-value: 'needs'. Located at position 1 within expression: needs.get-environment.outputs.environment_name
name: Environments
on:
push:
workflow_dispatch:
jobs:
get-environment:
runs-on: ubuntu-latest
outputs:
environment_name: ${{ steps.get_environment.outputs.environment_name }}
steps:
- id: get_environment
run: |
if [ "$GITHUB_REF" = "refs/heads/test" ]
then
echo "::set-output name=environment_name::test"
elif [ "$GITHUB_REF" = "refs/heads/qa" ]
then
echo "::set-output name=environment_name::qa"
elif [ "$GITHUB_REF" = "refs/heads/master" ]
then
echo "::set-output name=environment_name::production"
fi
use-environment:
runs-on: ubuntu-latest
needs: [get-environment]
environment: ${{ needs.get-environment.outputs.environment_name }}
steps:
- uses: actions/checkout#v2
- name: Run a one-line script
run: echo ${{ secrets.ENV_DEPENDENT_SECRET }}
Is it possible to achieve what I'm trying to do? My end goal is to have a single workflow file for three different app environments (test, QA and prod), where each app environment uses a separate Actions environment. (terminology gets confusing, I know)
I actually had to solve this issue for the place I work. You can use a matrix with the list of your env names and dynamically set the environment name. Take a look at the link for the workflow file.
Have you tried
> use-environment:
> runs-on: ubuntu-latest
> needs: [get-environment]
> environment:
> name: ${{ needs.get-environment.outputs.environment_name }}