Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Gitlab Variables in Gitlab README.md for SonarQube Badges

I'm using Gitlab and Sonarqube and the Sonarqube Plugin SVG Badges.
To represent the Sonarqube state on gitlab I have something like this in my README.md file:

[![coverage](https://sonar.domain.com/api/badges/measure?key=com.domain:projectname&metric=coverage)](https://sonar.domain.com/component_measures/metric/coverage/list?id=de.domain:projectname)

This works perfect. My badge is shown, the link is working, everything is fine.

Is there some way to build something like:

[![coverage](https://sonar.domain.com/api/badges/measure?key={MYDOMAIN}:{THIS}&metric=coverage)](https://sonar.domain.com/component_measures/metric/coverage/list?id={MYDOMAIN}:{THIS})

I want to provide a skeleton that every Developer just can copy and paste into their README.md file and the variables are filled into the README automatically, with something like .gitlab-ci.yml

I also tried the permanent Gitlab Variables mentioned here but that wasn't working too!

 [![coverage](https://sonar.domain.com/api/badges/measure?key=com.mydomain:$CI_PROJECT_NAME&metric=coverage)](https://sonar.domain.com/component_measures/metric/coverage/list?id={MYDOMAIN}:$CI_PROJECT_NAME)

Anyone has some idea?

like image 203
Joergi Avatar asked May 02 '17 16:05

Joergi


2 Answers

The variables in https://gitlab.com/help/ci/variables/README.md are present only in a CI environment (i.e. a job), so you can't use them in the Markdown viewer when displaying the file. - That's a great idea for a feature proposal, though. I opened one - https://gitlab.com/gitlab-org/gitlab-ce/issues/32255. Feel free to chime in.

What you could do is add a placeholder where you want those variables to go and then create a job which sed's them.

update_readme:
  script:
    - echo $CI_PROJECT_NAME # Sanity check
    - sed -ie "s/{THIS}/$CI_PROJECT_NAME/g" README.md

Note the use of double-quotes (") and not single quotes ('). Using double-quotes will interpolate $CI_PROJECT_NAME while single-quotes would just retain it's literal value.

like image 63
matteeyah Avatar answered Oct 14 '22 01:10

matteeyah


IMPORTANT!

You should implement a branch/logic to avoid triggering the .gitlab-ci.yml in an infinite loop because you are asking to update a repository file from the CI itself

The approach is:

  1. Prepare README.md with special delimiters around the badge
  2. Substitute old/initial badge by payload (you should build it, not shown here) in the repository loaded README.md
  3. urlencode the substituted content
  4. Update the repository with the Gitlab API

README.md

Hello
[//]: # (-- start --)
Initial non working badge
[//]: # (-- end --)
World

.gitlab-ci.yml

update_readme:
  script:
  - curl --request PUT --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v4/projects/13083/repository/README%2Emd?branch=master&content=$(urlencode "$(sed 's_\[//\]: # (-- end --)_\n&_g;s_\(\[//\]: # (-- start --)\)[^\n]*\n_\1\npayload\n_g' README.md)")&commit_message=update%20file'

In sed command, substitute payload with your actual badge (you should build it, not shown here)

  • The solution is to write the README.md using the Update existing file in repository API
  • The README.md should use the special string delimiters that do not appear rendered (they are like hidden comments). These delimiters are always in the file, they do not get substituted. Only what it is in between them get subtituted. This way you can automatically update the badge each time you run the .gitlab-ci.yml (only the badge get updated)
  • The substitution is done by the sed command so you need to add the path to the README.md
  • The update API needs the content to be urlencoded (so the sed command is wrapped by a bash urlencode() function that should be loaded first (loading not shown):

urlencode()

urlencode() {
    # urlencode <string>
    old_lc_collate=$LC_COLLATE
    LC_COLLATE=C

    local length="${#1}"
    for (( i = 0; i < length; i++ )); do
        local c="${1:i:1}"
        case $c in
            [a-zA-Z0-9.~_-]) printf "$c" ;;
            *) printf '%%%02X' "'$c" ;;
        esac
    done

    LC_COLLATE=$old_lc_collate
}

Notes: The [//]: # (-- start --) does not affect the render of your README.md so you can use it like hidden comments

Replace your private token with a Gitlab CI Secret variable

like image 38
elingerojo Avatar answered Oct 14 '22 00:10

elingerojo