This week was about setting up the documentation foundation for the rest of Fab Academy:
version control + documentation + publishing a website.
My goal was to end the week with:
- a site that publishes on Fab Academy GitLab Pages
- a clean Git workflow
- a repo that I can update every week without breaking everything
- about, weekly and final project pages
Laptop & Tools
- Device: MacBook Air
- OS: macOS Sequoia
- Shell: bash / zsh
- Editor: Visual Studio Code
- Terminal: VS Code built-in terminal
- Version control: Git
I chose to do all terminal operations from VS Code’s built-in terminal and markdown file edits from VS Code for convenience and because of its clean interface.
Git & Version Control
Git is a version control system that records changes to files over time, allowing me to track progress, revert mistakes, and experiment without losing work.
In Fab Academy, Git is essential because all documentation is stored and published from a single repository, meaning every weekly update builds on the previous one. By committing changes locally and pushing them to GitLab, I create a clear history of my work and ensure the website is safely updated and recoverable if something breaks.
Verifying Git Installation
Git was already installed on my Mac, but I confirmed it with:
git --version
Setting Up GitLab
Fab Academy provides an official GitLab account and repository through FabCloud, and that repo is what publishes to the class archive.
So instead of creating a new project, the correct workflow is:
- use the repo provided by Fab Academy
- push weekly updates there
- let CI publish it automatically
SSH Key Configuration for GitLab
SSH keys are useful because they let you connect securely to your GitLab account every time you push without the need of entering username and password.
1) Generate a new SSH key pair
ssh-keygen -t ed25519 -C "<your-email>"
2) Copy the public key
cat ~/.ssh/id_ed25519.pub
Then paste it into your GitLab account under:
Preferences → SSH Keys
3) Add the key to the SSH agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
4) Test the SSH connection
For FabCloud:
ssh -T git@gitlab.fabcloud.org
If SSH is working, GitLab will respond with a welcome message.
Cloning the Repository
After getting access to my FabCloud repository, I cloned it locally using the SSH link from:
Repo → Code → Clone with SSH
Example command:
git clone git@gitlab.fabcloud.org:.../...git
cd <repo-folder>
Installing Hugo
I didn’t have Hugo installed on this machine initially, so I installed it using Homebrew:
brew install hugo
To confirm it worked:
hugo version
Creating and Running a Hugo Website Locally
Choosing a Theme
I decided to use the BeautifulHugo theme because it has a clean layout and works well for weekly documentation.
Link to find themes for your hugo site: https://themes.gohugo.io/
Creating Hugo site inside my Fab repo
Since my FabCloud repo already exists, I didn’t create a separate folder like my-fab-site/.
Instead, I set up Hugo in the repository so I can push updates directly.
The key Hugo parts are:
content/→ pages/posts written in Markdownstatic/→ images + filesthemes/→ site themehugo.toml→ configuration
Adding the theme as a submodule
git submodule add https://github.com/halogenica/beautifulhugo.git themes/beautifulhugo
git submodule update --init --recursive
This matters because without submodules, the site would appear unstyled after cloning.
Previewing locally
To run the site locally and preview changes:
hugo server -D
This starts a local development server so I can check formatting, menus, and images before pushing.
Customizing hugo.toml
The hugo.toml file controls site settings like:
- site title
- theme
- navigation menu
- baseURL (important for Fab Academy)
A simplified example:
languageCode = "en-us"
title = "Poyraz Ozzengi | Fab Academy"
theme = "beautifulhugo"
[params]
mainSections = ["post"]
Navigation (menu)
I use dedicated pages for:
- Final Project
- Weekly Assignments
Example menu structure:
[menu]
[[menu.main]]
name = "Final Project"
url = "/page/final-project/"
weight = 30
[[menu.main]]
name = "Weekly Assignments"
url = "/page/weekly/"
weight = 20
Content Structure (How I organized my pages)
I used two main directories:
/content/page/
For “static” pages:
weekly.md(the weekly hub page)final-project.md
/content/post/
For blog-style posts and weekly pages:
week-01.mdweek-02.md- …
- personal pages (like About)
This keeps weekly assignments consistent and easy to find.
Images / Assets
All photos and screenshots go inside:
static/doc_assets/
Then I can use them in Markdown like:

This is the cleanest long-term method because it keeps everything in one place.
Adding .gitignore
Hugo generates some folders automatically every time it builds the website.
To avoid pushing generated files and create a possible error while pushing (because they will be created again), I created a .gitignore file and ignored Hugo build output like public/.
public/
resources/
.hugo_build.lock
.DS_Store
Deploying on GitLab Pages (CI)
To publish automatically, I used a GitLab CI configuration file:
.gitlab-ci.yml
This file tells GitLab:
- download the repo
- download theme submodules
- run Hugo build
- publish
public/
The idea is:
Edit → Commit → Push → Pipeline builds → Site updates
Basically, the pipeline build is triggered by .yml file
A working Hugo Pages pipeline
image: "registry.gitlab.com/pages/hugo/hugo_extended:latest"
variables:
HUGO_ENV: "production"
HUGO_BASEURL: "$CI_PAGES_URL/"
GIT_SUBMODULE_STRATEGY: "recursive"
pages:
stage: deploy
before_script:
- hugo version
- git submodule sync --recursive
- git submodule update --init --recursive
script:
- hugo --minify
artifacts:
paths:
- public
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
Why Hugo Extended?
Some themes rely on extended features (like SCSS). Using extended avoids random CI failures. (Got the explanation from ChatGPT)
Pushing to the Class GitLab Repository
Once the Hugo site + CI were ready, I pushed to FabCloud GitLab:
git add -A
git commit -m "Week 01 setup: Hugo + GitLab Pages"
git push
Then I checked the pipeline status in:
GitLab → Build → Pipelines
A green pipeline means the site published successfully.
Problems / Fails I Faced (and fixes)
1) “I committed but the website didn’t change”
I mixed up what Git actions do:
git commitsaves changes locallygit pushuploads them to GitLab- the site updates only after the pipeline finishes
Correct workflow:
git add -A
git commit -m "Update Week 01"
git push
2) Images existed but didn’t show
This was the biggest issue.
Even if the files exist, images can still break because of:
- wrong paths
- wrong capitalization (
.PNGvs.png)
My fix was to:
- keep images inside
static/doc_assets/ - double-check the file name is exactly the same as the Markdown link
- Write the correct folder path in my markdown page since Fab Academy hosts sites inside a long folder path
3) Confusion about public/
At first I thought public/ was something I should edit manually, but it’s actually the generated output.
Correct rules:
- edit
content/andstatic/ - Hugo generates
public/ - CI publishes
public/
Reflection
This week was mostly setup and troubleshooting, but it gave me a stable base for the whole year. The things I learnt are:
- idea of version controls
- main things like ssh, cloning, and submodules (themes)
- pulling, commiting and pushing
- .toml and .yaml files
- running a website on Fabcloud
- even small mistakes can break everything
My workflow is clear: write → preview → commit → push → pipeline → published site.