Automatic creation of a CHANGELOG.md with gitlab-ci.yml

For my Hugo Project I would like to program an automated creation of a changelog.md. I will using the .gitlab-ci.yml. The tutorial by Ben Ridley from the GitLab team serves as a template. Tutorial: Automate releases and release notes with GitLab

  1. I have created a Project Access Token (Active project access tokens) called CI_API_TOKEN
  2. in CI/CD Settings I have stored the CI_API_TOKEN in CI/CD Variables.

Unfortunately, no CHANGELOG.md is created. Since I use Hugo, I would like to have this CHANGELOG.md in contents/en/CHANGELOG.md with the following entry in the Frontmater:

CHANGELOG.md

---
title: "Changelog"
description: "Changelog"
draft: false
url: /changelog
menu:
    main:
        weight: 2
---

{{< row >}}

{{< column col-md-12 >}}

# Changelog

Here are the changelog entries from GitLab


{{< /column >}}

{{< /row >}}

.gitlab-ci.yml

 image: registry.gitlab.com/pages/hugo/hugo_extended:latest

variables:
   HUGO_ENV: production

default:
  before_script:
    - apk add dart-sass --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
    - apk add --no-cache dart-sass go curl jq

stages:
  - prepare
  - release
  - test

prepare_job:
  stage: prepare
  rules:
  - if: '$CI_COMMIT_TAG =~ /^v?\d+\.\d+\.\d+$/'
  script:
    - 'curl -H "PRIVATE-TOKEN: $CI_API_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/changelog?version=$CI_COMMIT_TAG" | jq -r .notes > release_notes.md'
    - 'curl -H "PRIVATE-TOKEN: $CI_API_TOKEN" -X POST "$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/changelog?version=$CI_COMMIT_TAG"'
  artifacts:
    paths:
    - release_notes.md

release_job:
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  needs:
    - job: prepare_job
      artifacts: true
  rules:
  - if: '$CI_COMMIT_TAG =~ /^v?\d+\.\d+\.\d+$/'
  script:
    - echo "Creating release"
  release:
    name: 'Release $CI_COMMIT_TAG'
    description: release_notes.md
    tag_name: '$CI_COMMIT_TAG'
    ref: '$CI_COMMIT_SHA'
    assets:
      links:
        - name: 'Container Image $CI_COMMIT_TAG'
          url: "https://$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA"


test:
  script:
    - hugo --minify
  rules:
    - if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH

pages:
  script:
    - hugo --minify
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
    # If you want schedule then comment out this line
    # - if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "schedule"'
Running with gitlab-runner 16.11.0~pre.21.gaa21be2d (aa21be2d)
  on blue-4.saas-linux-small-amd64.runners-manager.gitlab.com/default J2nyww-s, system ID: s_cf1798852952
  feature flags: FF_USE_IMPROVED_URL_MASKING:true
Preparing the "docker+machine" executor
00:06
Using Docker executor with image registry.gitlab.com/pages/hugo/hugo_extended:latest ...
Authenticating with credentials from job payload (GitLab Registry)
Pulling docker image registry.gitlab.com/pages/hugo/hugo_extended:latest ...
Using docker image sha256:1edb6357ff8fbebf2876aa6bfb16cb399b40bedacdc5fe6816476e6f73b62e17 for registry.gitlab.com/pages/hugo/hugo_extended:latest with digest registry.gitlab.com/pages/hugo/hugo_extended@sha256:a87ca44e3a5096948307875d1a896b21b58df61ef259f5fe776c1e599b83ab4a ...
Preparing environment
00:01
Running on runner-j2nyww-s-project-57130790-concurrent-0 via runner-j2nyww-s-s-l-s-amd64-1713869985-c8db2df4...
Getting source from Git repository
00:02
Fetching changes with git depth set to 20...
Initialized empty Git repository in /builds/joklein/developer/.git/
Created fresh repository.
Checking out 4a81fd27 as detached HEAD (ref is main)...
Skipping Git submodules setup
$ git remote set-url origin "${CI_REPOSITORY_URL}"
Executing "step_script" stage of the job script
00:13
Using docker image sha256:1edb6357ff8fbebf2876aa6bfb16cb399b40bedacdc5fe6816476e6f73b62e17 for registry.gitlab.com/pages/hugo/hugo_extended:latest with digest registry.gitlab.com/pages/hugo/hugo_extended@sha256:a87ca44e3a5096948307875d1a896b21b58df61ef259f5fe776c1e599b83ab4a ...
$ apk add dart-sass --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
fetch http://dl-cdn.alpinelinux.org/alpine/edge/testing/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.19/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.19/community/x86_64/APKINDEX.tar.gz
(1/4) Installing icu-data-en (74.1-r0)
Executing icu-data-en-74.1-r0.post-install
*
* If you need ICU with non-English locales and legacy charset support, install
* package icu-data-full.
*
(2/4) Installing icu-libs (74.1-r0)
(3/4) Installing dartaotruntime (3.3.2-r0)
(4/4) Installing dart-sass (1.75.0-r0)
Executing busybox-1.36.1-r15.trigger
OK: 38 MiB in 35 packages
$ apk add --no-cache dart-sass go curl jq
fetch https://dl-cdn.alpinelinux.org/alpine/v3.19/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.19/community/x86_64/APKINDEX.tar.gz
(1/15) Installing curl (8.5.0-r0)
(2/15) Installing jansson (2.14-r4)
(3/15) Installing zstd-libs (1.5.5-r8)
(4/15) Installing binutils (2.41-r0)
(5/15) Installing libgomp (13.2.1_git20231014-r0)
(6/15) Installing libatomic (13.2.1_git20231014-r0)
(7/15) Installing gmp (6.3.0-r0)
(8/15) Installing isl26 (0.26-r1)
(9/15) Installing mpfr4 (4.2.1-r0)
(10/15) Installing mpc1 (1.3.1-r1)
(11/15) Installing gcc (13.2.1_git20231014-r0)
(12/15) Installing musl-dev (1.2.4_git20230717-r4)
(13/15) Installing go (1.21.9-r0)
(14/15) Installing oniguruma (6.9.9-r0)
(15/15) Installing jq (1.7.1-r0)
Executing busybox-1.36.1-r15.trigger
OK: 362 MiB in 50 packages
$ hugo --minify
hugo: downloading modules …
hugo: collected modules in 5931 ms
Start building sites … 
hugo v0.125.3+extended linux/amd64 BuildDate=unknown
                   | EN  
-------------------+-----
  Pages            | 16  
  Paginator pages  |  0  
  Non-page files   |  0  
  Static files     | 13  
  Processed images |  0  
  Aliases          |  0  
  Cleaned          |  0  
Total in 6314 ms
Uploading artifacts for successful job
00:03
Uploading artifacts...
public: found 46 matching artifact files and directories 
WARNING: Upload request redirected                  location=https://gitlab.com/api/v4/jobs/6694495022/artifacts?artifact_format=zip&artifact_type=archive new-url=https://gitlab.com
WARNING: Retrying...                                context=artifacts-uploader error=request redirected
Uploading artifacts as "archive" to coordinator... 201 Created  id=6694495022 responseStatus=201 Created token=glcbt-65
Cleaning up project directory and file based variables
00:00
Job succeeded

It seems that curl doesn’t work as aspected. What I do wrong?