On Pipelines as Code we started to get a nice documentation website on :
The website is statically generated with Hugo and hosted on CloudFares Pages using the markdown files from the repository.
So far that’s a pretty standard stack, but what we wanted is to be able to get preview URLS like on Netlify or other CIs
There is a nice check box, that says “Generate Preview URL on Pull Request”
which seems to do what we want but it doesn’t. So far it seems that Pull Request coming from forks are not processed only the one from branch coming
from the same repository where the pull request is.
Since we do our own dogfood and we want anyway to use Pipelines as Code and
Tekton as much as possible, I started to implement a preview environement
mechanism to get a link with the changes from the pull request if the doc/
folder is modified inside the PR.
I have again used my toy webserver, go-simple-uploader (which we have been used previously for artifacts caching) to serve the static HTML generate with hugo, but first I had to make a few changes to it:
Added an OpenShift Route to directly expose it to the internet. It previously was only accessible via the local kubernetes service across pods.
I added a capability to be able to send a tarball when uploading, so we can upload a tarball of a folder and stream directly to
go-simple-uploaderwhich will uncompress it on the fly.I modified the server to add authentication to the
/uploadendpoint via a username and password. Just to make sure nobody abuse from it.
So far so good and after having the new image deployed on our cluster, I
modified our Pipelines as Code/Tekton template in the .tekton directory
to get those preview URLS generated.
The whole bits added is here :
- name: build-doc
runAfter:
- fetchit
taskSpec:
workspaces:
- name: source
steps:
- name: hugo-gen
image: quay.io/thegeeklab/hugo
workingDir: $(workspaces.source.path)
script: |
git fetch origin main && \
git diff --name-only FETCH_HEAD | grep -q '^docs/' || exit 0
cd docs
sed -i '1acanonifyURLs = true' config.toml
hugo --gc --minify -d {{ revision }} -b https://preview-pipelines-as-code-ci.apps.paac.devcluster.openshift.com/docs/{{ revision }}
echo "Preview URL: https://preview-pipelines-as-code-ci.apps.paac.devcluster.openshift.com/docs/{{ revision }}"
- name: upload-to-static-server
# it has curl and we already pulled it
image: registry.redhat.io/rhel8/go-toolset:1.16.12-7
workingDir: $(workspaces.source.path)
env:
- name: HUB_TOKEN
valueFrom:
secretKeyRef:
name: "nightly-ci-github-hub-token"
key: "hub-token"
- name: UPLOADER_UPLOAD_CREDENTIALS
valueFrom:
secretKeyRef:
name: "uploader-upload-credentials"
key: "credentials"
script: |
cd docs
[[ -d {{ revision }} ]] || exit 0
tar czf - {{ revision }} | curl -u ${UPLOADER_UPLOAD_CREDENTIALS} -F path=docs -F targz=true -X POST -F file=@- http://uploader:8080/upload
# Post as status
set +x
curl -H "Authorization: Bearer ${HUB_TOKEN}" -H 'Accept: application/vnd.github.v3+json' -X POST https://api.github.com/repos/{{repo_owner}}/{{repo_name}}/statuses/{{revision}} -d '{"state": "success", "target_url": "https://preview-pipelines-as-code-ci.apps.paac.devcluster.openshift.com/docs/{{ revision }}", "description": "Generated with brio.", "context": "Pipelines as Code Preview URL"}'
On the first step we start detecting if we had any changes in the doc/ folder
using some git trickery with FETCH_HEAD, if we didn’t have any we will just
exit 0 and skip it.
If we have some changes, we add a setting to the hugo config.toml file to set
cannonifyURLs=true so we get canon urls instead of relative.
We are then generating the documentation using hugo and we add the new base
which goes to our public route URL and the commit sha (via Pipelines as Code variable expansion).
We have another step just after, that would use the username and password from
a secret on a cluster and tar gz the new docs/ folder on the file to
go-simple-uploader which will upload it and uncompress it on the service.
At the end to be able to preview URL, I wasn’t sure which place to put it, we
could do slack or as a comment of the pull request but this quickly become
ignore and spammy. Instead, I used the GitHub statuses API to post the link
inside the pull request in the CI status place of GitHub, just a click away to
be previewed.
Links
Screenshot
