commit 6873a23df6340a15d408ac5c7a0162b6481ffa6e
parent 2788db41cc551edf39eb0bbb36dd869c9a36d4e1
Author: Robert Lützner <robert.luetzner@pm.me>
Date: Wed, 3 Jul 2024 08:53:26 +0200
CI: Migrate pipeline from GitHub to Woodpecker CI
This rebuilds the pipeline that we used with GitHub's CI for Codeberg's
CI, which currently uses Woodpecker.
This immediately revealed a few key differences between the two CIs,
most prominently that we need a separate script to generate a pull
request with a dynamic title and body.
While there **is** a plugin for Woodpecker that can be used to generate
a pull request, any variables in the pipeline will be replaced when the
pipeline is started, not when the step is executed. In practice this
means that we can't use the `READABLE_CSS_TAG` variable from a previous
step.
I worked around that by using a `golang` docker container instead,
building the `gitea-pull-request-create-plugin` from source and
populating the necessary environment variables in a bash script, instead
of using the YAML pipeline.
The steps for how to enable the Woodpecker CI for Codeberg are
documented here:
https://docs.codeberg.org/ci/
We'll need an API token for Codeberg, which can be created by
1. logging on to codeberg.org,
2. navigating to 'Settings',
3. clicking 'Applications' in the navigation bar on the left and
4. creating a new token with 'Read and write access' to repositories.
Once access to the CI has been enabled, the Git repo hugo-theme-readable
needs to be added and configured.
- On the 'Secrets' tab add a new 'cb_token' that contains the API token
for codeberg.org. The token needs to be available for 'cron' and
'manual' events.
- On the 'Crons' tab add a new cronjob named 'every_night' for the
default branch (can be left empty) and scheduled for '0 28 3 * * *'.
I assume that the pipeline needs to be run once manually to register the
'cron' event, but I'm not 100% sure.
This fixes #28.
Diffstat:
5 files changed, 122 insertions(+), 91 deletions(-)
diff --git a/.github/scripts/update-readable-css.sh b/.github/scripts/update-readable-css.sh
@@ -1,49 +0,0 @@
-#!/bin/bash
-set -o errexit
-set -o pipefail
-set -o nounset
-
-# Query the codeberg.org API (see
-# https://codeberg.org/api/swagger#/repository/repoListReleases
-# ) and use jq to get the tag name of the
-# latest release (i.e. the first element of the
-# array in the JSON output, that is not a
-# prerelease).
-# The '-r' option will give us "raw" output,
-# i.e. without surrounding double-quotes.
-# We use 'map' and 'select' in combination,
-# because jq won't return a list otherwise.
-# Only using 'select' returns just the matching
-# elements, which is not a valid json that we
-# can process further.
-TAG_VERSION=$(curl -s \
- -H 'accept: application/json' \
- https://codeberg.org/api/v1/repos/Freedom-to-Write/readable.css/releases \
- | jq -r '.|map(select(.prerelease==false))[0].tag_name')
-
-echo "Latest tag: ${TAG_VERSION}"
-
-# Get the current version.
-# The '-o' option will only output the match grep found.
-# We look for readable.min.css and a set of three numbers seperated by dots,
-# i.e. a semantic version. readable.min.css is used to make sure that we match
-# the right numbers in the file.
-# We use sed to get rid of the readable.min.css prefix.
-CURRENT_VERSION=$(grep -o \
- 'readable.min.css?v=v[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+' \
- layouts/partials/head.html \
- | sed 's/readable.min.css?v=//')
-echo "Current version: ${CURRENT_VERSION}"
-
-if [[ $TAG_VERSION == $CURRENT_VERSION ]]
-then
- echo "Nothing to do. The current version is already up to date."
-else
- curl -s "https://codeberg.org/Freedom-to-Write/readable.css/raw/tag/${TAG_VERSION}/readable.css" > static/css/readable.css
- curl -s "https://codeberg.org/Freedom-to-Write/readable.css/raw/tag/${TAG_VERSION}/readable.min.css" > static/css/readable.min.css
- sed -i "s/readable.min.css?v=${CURRENT_VERSION}/readable.min.css?v=${TAG_VERSION}/" layouts/partials/head.html
-fi
-
-# Add the latest tag version to the workflow environment, so we can access
-# it in later steps.
-echo "READABLE_CSS_TAG=${TAG_VERSION}" >> "$GITHUB_ENV"
diff --git a/.github/workflows/update-readable-css.yml b/.github/workflows/update-readable-css.yml
@@ -1,42 +0,0 @@
-name: update-readable-css
-
-on:
- schedule:
- # Every day at 3:28.
- - cron: '28 3 * * *'
-
-jobs:
- update-readable-css:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: Download CSS files for latest tag
- run: .github/scripts/update-readable-css.sh
- - name: Create pull request if files have changed
- # https://github.com/marketplace/actions/create-pull-request
- uses: peter-evans/create-pull-request@v5
- with:
- # First line is the commit subject as always. The rest goes
- # into the body.
- commit-message: |
- Update readable.css to ${{ env.READABLE_CSS_TAG }}
-
- See the changelog here:
-
- https://codeberg.org/Freedom-to-Write/readable.css/src/tag/${{ env.READABLE_CSS_TAG }}/CHANGELOG.md
- branch: update-readable-css
- delete-branch: true
- # Use 'GitHub' both times.
- # This is already the default for committer, but the author defaults
- # to the user who triggered the workflow run, which is the owner of
- # the repository.
- # We use the same value for the author to indicate that the
- # commit was created by a bot.
- committer: GitHub <noreply@github.com>
- author: GitHub <noreply@github.com>
- title: Update readable.css to ${{ env.READABLE_CSS_TAG }}
- body: |
- See the changelog here:
-
- https://codeberg.org/Freedom-to-Write/readable.css/src/tag/${{ env.READABLE_CSS_TAG }}/CHANGELOG.md
- labels: update-readable-css
diff --git a/.woodpecker/.update-readable-css.yml b/.woodpecker/.update-readable-css.yml
@@ -0,0 +1,20 @@
+when:
+ - event: manual
+ - event: cron
+ cron: every_night
+
+steps:
+ update-readable-css:
+ image: golang:latest
+ environment:
+ CB_TOKEN:
+ from_secret: cb_token
+ PULL_REQUEST_BRANCH: update-readable-css
+ commands:
+ # This docker image comes with git and curl, but we still need to install
+ # jq.
+ - apt-get update
+ - apt-get install -y jq
+
+ - .woodpecker/scripts/update-readable-css.sh
+ - .woodpecker/scripts/create-codeberg-pull-request.sh
diff --git a/.woodpecker/scripts/create-codeberg-pull-request.sh b/.woodpecker/scripts/create-codeberg-pull-request.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+set -o errexit
+set -o pipefail
+set -o nounset
+
+source envvars
+
+if [[ "${READABLE_CSS_CHANGED}" != "true" ]]; then
+ echo "Skip pull request."
+ exit 0
+fi
+
+# This is actually a Woodpecker CI plugin.
+# However, Woodpecker pipelines are currently not able to set plugin values
+# from previous steps.
+# We need a way to dynamically set the pull request title and body, so we used
+# env variables instead and build the project ourselves.
+git clone https://codeberg.org/JohnWalkerx/gitea-pull-request-create-plugin
+(cd gitea-pull-request-create-plugin; go build)
+
+export PLUGIN_GITEA_ADDRESS='https://codeberg.org'
+export PLUGIN_GITEA_TOKEN="${CB_TOKEN}"
+
+export PLUGIN_OWNER="${CI_REPO_OWNER}"
+export PLUGIN_REPO="${CI_REPO_NAME}"
+export PLUGIN_BRANCH="${PULL_REQUEST_BRANCH}"
+export PLUGIN_BASE_BRANCH='main'
+
+export PLUGIN_PR_TITLE="Update readable.css to ${READABLE_CSS_TAG}"
+PLUGIN_PR_BODY=$(cat << EOF
+See the changelog here:
+
+https://codeberg.org/Freedom-to-Write/readable.css/src/tag/${READABLE_CSS_TAG}/CHANGELOG.md
+EOF
+)
+export PLUGIN_PR_BODY
+
+gitea-pull-request-create-plugin/gitea-pull-request-create-plugin
diff --git a/.woodpecker/scripts/update-readable-css.sh b/.woodpecker/scripts/update-readable-css.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+set -o errexit
+set -o pipefail
+set -o nounset
+
+# Query the codeberg.org API (see
+# https://codeberg.org/api/swagger#/repository/repoListReleases
+# ) and use jq to get the tag name of the
+# latest release (i.e. the first element of the
+# array in the JSON output, that is not a
+# prerelease).
+# The '-r' option will give us "raw" output,
+# i.e. without surrounding double-quotes.
+# We use 'map' and 'select' in combination,
+# because jq won't return a list otherwise.
+# Only using 'select' returns just the matching
+# elements, which is not a valid json that we
+# can process further.
+TAG_VERSION=$(curl -s \
+ -H 'accept: application/json' \
+ https://codeberg.org/api/v1/repos/Freedom-to-Write/readable.css/releases \
+ | jq -r '.|map(select(.prerelease==false))[0].tag_name')
+
+echo "Latest tag: ${TAG_VERSION}"
+
+# Get the current version.
+# The '-o' option will only output the match grep found.
+# We look for readable.min.css and a set of three numbers seperated by dots,
+# i.e. a semantic version. readable.min.css is used to make sure that we match
+# the right numbers in the file.
+# We use sed to get rid of the readable.min.css prefix.
+CURRENT_VERSION=$(grep -o \
+ 'readable.min.css?v=v[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+' \
+ layouts/partials/head.html \
+ | sed 's/readable.min.css?v=//')
+echo "Current version: ${CURRENT_VERSION}"
+
+if [[ $TAG_VERSION == $CURRENT_VERSION ]]
+then
+ echo "Nothing to do. The current version is already up to date."
+ # Inform the next script that it can exit early.
+ echo "READABLE_CSS_CHANGED=false" >> envvars
+ exit 0
+fi
+
+# Update CSS files
+curl -s "https://codeberg.org/Freedom-to-Write/readable.css/raw/tag/${TAG_VERSION}/readable.css" > static/css/readable.css
+curl -s "https://codeberg.org/Freedom-to-Write/readable.css/raw/tag/${TAG_VERSION}/readable.min.css" > static/css/readable.min.css
+
+# Replace version in head.html
+sed -i "s/readable.min.css?v=${CURRENT_VERSION}/readable.min.css?v=${TAG_VERSION}/" layouts/partials/head.html
+
+# Create a new commit on a new branch.
+git checkout -b "${PULL_REQUEST_BRANCH}"
+git config --global user.name 'Codeberg CI'
+git config --global user.email 'noreply@codeberg.org'
+git commit -a -m "Update readable.css to ${TAG_VERSION}" -m "See the changelog here:" -m "https://codeberg.org/Freedom-to-Write/readable.css/src/tag/${TAG_VERSION}/CHANGELOG.md"
+git remote set-url origin "https://$CB_TOKEN@codeberg.org/$CI_REPO_OWNER/$CI_REPO_NAME.git"
+git push --force --set-upstream origin "${PULL_REQUEST_BRANCH}"
+
+# Add the latest tag version to the workflow environment, so we can access
+# it in later steps.
+echo "READABLE_CSS_TAG=${TAG_VERSION}" >> envvars
+echo "READABLE_CSS_CHANGED=true" >> envvars