Assignment
- make the website for CBA's self-hosted GitLab
Where we started
Well, all of us in the HTMAA class started with an blank site on the GitLab repo, deployed by a GitLab CI job to pull the repository into a Nginx server.
# .gitlab-ci.yml
job:
script:
- mkdir -p /var/www/classes/863.25/people/YufengZhao
- export GIT_WORK_TREE=/var/www/classes/863.25/people/YufengZhao/
- git checkout -f main
- git pull
However, this doesn't include a build step, which is required for a static site generator. Because I really don't want to write raw HTML and CSS for this type of blog site, I decided to find a workaround.
Site Genration on CBA's GitLab
In 2024, I spent a lot of time to make my personal website easier to maintain. I ended up building a MDX component library powered by a Next.js Static Site Generator (SSG). The Content Management System (CMS) is just a simple GitLab repository.

I think it looks pretty sweet, and I'm quite used to writing my custom MDX syntax. The first thing I did was to copy the entire repository and modify it to fit the CBA's GitLab. In order to make it work, I had to modify the CI job to build the website.
# .gitlab-ci.yml, modified
stages:
- build
- deploy
variables:
BUN_VERSION: "latest"
build:
stage: build
cache:
paths:
- ~/.bun/install/cache/
- node_modules/
- .next/cache/
before_script:
# Install Bun
- curl -fsSL https://bun.sh/install | bash
# Add Bun to PATH for current session
- export PATH="$HOME/.bun/bin:$PATH"
# Verify installation
- bun --version
script:
- export PATH="$HOME/.bun/bin:$PATH"
- bun install
- bun run build
artifacts:
paths:
- out/
expire_in: 1 hour
only:
- main
deploy:
stage: deploy
dependencies:
- build
script:
- mkdir -p /var/www/classes/863.25/people/YufengZhao
- rm -rf /var/www/classes/863.25/people/YufengZhao/*
- cp -r out/* /var/www/classes/863.25/people/YufengZhao/
only:
- main
I chose to install Bun on the CI runner to build my Next.js website. However, the pipeline job not only failed but also froze the entire GitLab server for about 30 minutes (thank god I was doing it during midnight). I realized the GitLab server is probably quite slow, so I immediately reverted the CI configuration.
Separation of Source Code and Output
Thankfully, I'm not the only person who has this problem. My classmate Sun Chuanqi's decided to separate the source code and the output. Here's a summary of his approach:
Source code
Sun moved his source code to Github, which is faster than CBA's GitLab.
Building and Deploying Output
Using Github Action to build the site and commit the output to the GitLab repository.
This is his repository, and here's the Github Action.
# Setup
# =====
# 1. Go to GitLab, generate a developer acccess token with `write_repository` scope. In the UI, it's in settings > access tokens.
# 2. Go to GitHub, add that token to your GitHub repo's secrets list
# 3. In GitLab, relax branch protection policy to allow direct push permission on the `main` branch by your user's role. In my case, the role is `Developer`, not `Maintainer`.
# 4. Edit this file, replace `SunChuanqi` with your GitLab username in two places, your commiter name and email with yours.
# 5. Adjust build script and deployment folder to match your static site generator. Mine is `public`.
name: Build and push to GitLab
on:
push:
branches: ["master"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node.js version
uses: actions/setup-node@v4
with:
node-version: "22.x"
- name: Check out gitlab repo
# Customize git clone url here
run: |
git clone https://SunChuanqi:${{ secrets.GITLAB_ACCESS_TOKEN }}@gitlab.cba.mit.edu/classes/863.25/people/SunChuanqi.git public
- name: npm
# Customize build script here
run: |
npm install
npm run build
- name: Push
# Customize deployment folder here
run: |
cd public
git config --global user.name "Sun, Chuanqi"
git config --global user.email "stack@mit.edu"
git add .
git commit -m "${{ github.event.head_commit.message }}"
git status
git push origin main
As written in Sun's instruction, in order for the Github Action to work, I had to add the GitLab access token to the Github repository's secrets, and relax the branch protection policy to allow direct push permission on the main branch. Here's the screenshots of how to do them:
Getting the GitLab access token

Relaxing the branch protection policy

Adding the GitLab access token to the Github repository's secrets

Deployed!
Boom! Now when you commit to your Github repository, npm run build will be run automatically, and the output folder will be committed to the root of the GitLab repository.
The source code for my website is here, and the output GitLab repository is here, and the website is here.

References
"Design" Files
- My website(you are here)
- Output GitLab repo
- Source code on Github

