How to Publish a Static Website with Quarkus, Roq, and GitHub Actions
Step-by-step guide for Java developers to generate and continuously deploy static sites using Quarkus and Roq.
Creating a static website with Quarkus and Roq combines the power of Java’s best cloud-native framework with the simplicity of a modern static site generator. In this hands-on tutorial, you’ll learn how to build a static website, preview it locally, and automate deployments to GitHub Pages using GitHub Actions. This tutorial will guide you through:
Creating a new Roq static site.
Running the site in development mode.
Configuring a GitHub Action to automatically build and deploy your site to GitHub Pages.
Static sites are fast, secure, and easy to host. For developer portfolios, documentation, or project landing pages, they are often a better fit than a full CMS. With Roq, you get a Java-native approach to static site generation. With Qute templates, Markdown content, and the Quarkus development model you already know.
Automated deployment to GitHub Pages means that every push to your main branch instantly updates your public website. No manual builds, no extra hosting.
Prerequisites
Before you start, make sure you have the following tools installed:
An IDE (e.g., VSCode, IntelliJ, IBM Bob)
JDK 21+
Apache Maven 3.9.1+
The Quarkus CLI (optional, but recommended)
A GitHub account
I have set this up on my own github.io site and you are more than welcome to check out the configuration.
Create Your Roq Website
The easiest way to start is by using the Quarkus CLI to create a new project with the quarkus-roq extension.
Open your terminal and run the following command:
quarkus create app myfear-pages -x=io.quarkiverse.roq:quarkus-roqThis command creates a new directory named roq-github-pages containing a pre-configured Quarkus project with Roq. The quarkus-roq extension bundle includes everything you need, including the Qute template engine, FrontMatter support, and the static site generator.
If you don’t have the Quarkus CLI, you can use the following Maven command:
mvn io.quarkus.platform:quarkus-maven-plugin:create \
-DprojectGroupId=org.example \
-DprojectArtifactId=roq-github-pages \
-Dextensions=”io.quarkiverse.roq:quarkus-roq”Run in Development Mode
Now, let’s run the site locally.
Navigate into your new project directory:
cd roq-github-pagesStart Quarkus in development mode:
quarkus dev(or
./mvnw quarkus:dev)Open your browser and go to http://localhost:8080
You will see your new Roq website. Thanks to Quarkus’s live coding, any changes you make to the files in src/main/resources/roq will be reflected immediately in your browser.
Content: Add new pages by creating Markdown (
.md) or Qute (.html) files insrc/main/resources/roq/content/.Templates: Modify the layout in
src/main/resources/roq/templates/.
Create a GitHub Repository
Next, you’ll create a GitHub repository to host your project’s code and the final published website.
Go to GitHub and create a new public repository. Let’s call it
roq-github-pages.Initialize Git in your local project and push your code to the new repository.
# Initialize git
git init -b main
git add .
git commit -m “Initial commit”
# Add your new GitHub repository as the remote
git remote add origin https://github.com/YOUR-USERNAME/roq-github-pages.git
# Push your code
git push -u origin main
Note: Replace YOUR-USERNAME with your actual GitHub username.
Configure the GitHub Pages Action
The quarkus-roq extension integrates smoothly with GitHub Actions for deployment. The recommended approach uses GitHub’s artifact-based deployment for Pages, which is faster and doesn’t require a separate gh-pages branch.
This action workflow will:
Build your project and generate the static site files.
Upload these files as a special
github-pagesartifact.Deploy this artifact to GitHub Pages.
Follow these steps:
In your local project, create the directory path if it doesn’t exist (roq generates a basic file for you!):
.github/workflows/.Inside that directory, create a new file named
gh-pages.yml.Copy and paste the following content into your
gh-pages.ymlfile:
name: Deploy GitHub Pages
on:
# Runs on pushes targeting the default branch
push:
branches: [”main”] # Or your default branch name
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: “pages”
cancel-in-progress: false
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# This is the official Roq action to build the site and prepare the artifact
- name: Build Roq Site
id: build-roq
uses: quarkiverse/quarkus-roq@main
with:
# The directory containing your site’s pom.xml (relative to repository root)
# Optional: defaults to the root if not specified.
site-directory: ‘myfear-pages’ # <-- Adjust if your site isn’t in ‘myfear-pages’ like mine is :)
# Optional: Use a specific Maven executable if needed
maven-executable: ‘mvn’
# GITHUB_TOKEN is automatically used by the action for internal setup
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build # Runs only after the build job successfully completes
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4 # Uses the official Pages deployment action
# This action automatically retrieves the artifact uploaded by quarkiverse/quarkus-roq
This workflow file does the following:
on: Triggers the workflow on pushes to themainbranch or when manually run (workflow_dispatch).permissions: Grants the necessary permissions for theGITHUB_TOKENto read repository contents and write deployment information to GitHub Pages.concurrency: Ensures only one deployment runs at a time.jobs: Defines the sequence of tasks.buildjob:Checks out your repository’s code (
actions/checkout).Uses the
quarkiverse/quarkus-roqaction. This action automatically handles:Setting up the correct Java version.
Building your Quarkus application using Maven (
mvn package quarkus:run -Dquarkus.roq.generator.batch=true ...).Running the
roq-generatorto create the static site files (HTML, CSS, JS, etc.).Uploading the generated static files from the output directory (e.g.,
myfear-pages/target/roq) as agithub-pagesartifact (usingactions/upload-pages-artifactinternally).
deployjob:Runs after the
buildjob completes (needs: build).Sets up the GitHub Pages deployment environment.
Uses the official
actions/deploy-pagesaction, which automatically finds thegithub-pagesartifact uploaded by thebuildjob and deploys it to your GitHub Pages site.
Configure Your Repository and Deploy
You’re almost done.
Commit and push the workflow file:
git add .github/workflows/gh-pages.yml
git commit -m “Add GitHub Pages deployment workflow”
git pushConfigure GitHub Pages Source:
Go to your GitHub repository’s page.
Click on the Settings tab.
In the left-hand menu, click on Pages.
Under “Build and deployment”, change the Source from “Deploy from a branch” to “GitHub Actions”.
Trigger the First Deploy:
The push you just made should have already triggered the action.
Click on the Actions tab in your repository to see the “Deploy GitHub Pages” workflow running.
Wait for the action to complete successfully. It may take a minute or two.
Once the action is complete, your website will be published! You can find it at:
https://YOUR-USERNAME.github.io/
You’ve built a fully automated static site powered by Quarkus, Roq, and GitHub Pages.
From Markdown to live pages, every change is deployed within minutes and no external CI/CD setup required.
A modern, Java-native workflow for developers who prefer code over configuration.



