Using Gitlab Variables in Gitlab README.md for SonarQube Badges
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:
- Prepare
README.md
with special delimiters around the badge - Substitute old/initial badge by
payload
(you should build it, not shown here) in the repository loadedREADME.md
- urlencode the substituted content
- 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 theREADME.md
- The update API needs the
content
to be urlencoded (so thesed
command is wrapped by a bashurlencode()
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
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.