Using the API to add Codacy Grade details to the Readme
Some context
Codacy has a badge mechanism that can be included in your Readme file. It gives you an idea of the grade of your repository, from A to F, but sometimes that’s just not enough.
Fortunately, the new Codacy V3 API gives us a lot of new endpoints with useful information.
In order to learn more about API consumption on pipelines, I’ve purposed myself to find a way to put these metrics on the Readme file of a sample repository with a handicap: will not use pre-commit.
Prerequisites — A Placeholder
Since the grade details tendentially changes in each commit, it’s wise to have a placeholder inside the README.md file that we can fill with a sed script. Something like:
# An amazing repository with code<!-- codacy-status --> <!-- /codacy-status -->
Hands-on
My first idea was to use a GitHub Action on the main branch, call the API and update the readme file. It failed 🤬! My main branch is protected and Actions force commits into protected branches are not allowed. Yes, I know I can turn that off but it would defeat the purpose.
So the path is to trigger the action from the feature branches using the following GHA example:
name: Update Readmeon: push: branches-ignore: - masterjobs: update-readme: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: ref: $ - name: update README.md with codacy status run: | RETRIES=0 ANALYZED=$(curl -X GET https://app.codacy.com/api/v3/analysis/organizations/gh/codacy-acme/repositories/nodeproject/commits/${GITHUB_SHA}/deltaStatistics -H 'api-token: $' | jq '.analyzed') while [ $ANALYZED != "true" ] do sleep 10s RETRIES=$((RETRIES+1)) if [ "$RETRIES" -gt "10" ]; then echo "pipeline will exit due to max retries (10)" exit 0 fi ANALYZED=$(curl -X GET https://app.codacy.com/api/v3/analysis/organizations/gh/codacy-acme/repositories/nodeproject/commits/${GITHUB_SHA}/deltaStatistics -H 'api-token: $' | jq '.analyzed') done RESULT=$(curl https://app.codacy.com/api/v3/analysis/organizations/gh/codacy-acme/repositories/nodeproject | jq -r -j '["Grade: \(.data.grade) |", "Issues: \(.data.issuesPercentage)% |", "Complex Files: \(.data.complexFilesPercentage)% |", "Coverage: \(.data.coverage.coveragePercentage)%"]' | tr -d \" | tr -d \[ | tr -d \] | tr -d , | tr -d '\n') sed -i ":a;N;\$!ba;s/\(<!-- codacy-status -->\).*\(<!-- \/codacy-status -->\)/\1 \n$RESULT\n \2/g" README.md env: CI: true - uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: "Update README.md with Project Grade" file_pattern: README.md
In this snippet, we check if the commit is already analysed and, if it is, we’ll replace the content between the placeholder tags with the new metrics. There’s also a “max retries” mechanism in case PR doesn’t exist yet (other validation mechanisms can be considered here).
After the merge, README.md will have the current grade details
But there’s a…
Downside
Following this approach, there’s a huge limitation: the result will be the one before the merge. In order to avoid this, there’s a mandatory convention you should follow: do a rebase before merging.
Not perfect, I know but the purpose of this article is to demonstrate the power of the V3 API and how it can bring value outside the regular use cases. For instance, this endpoint can be used in a pipeline checkpoint.
Do you have any other “weird” use case? Let me know!
If you’d like to learn more about using the Codacy API, please check our docs page on the API v3. For more on our product and updates on our static analysis tool, check out Codacy’s product page.
This article was originally published by Hélio, Sr. Solutions Engineer at Codacy on his Medium account.