Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/validate-jenkins-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Validate Jenkins Shell Tests
permissions:
contents: read

on:
pull_request:
paths:
- "Jenkinsfile"
- "ci/jenkins/**"
- ".github/workflows/validate-jenkins-tests.yml"
workflow_dispatch:

jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v5

- name: Run Jenkins shell tests
shell: bash
run: |
set -xeuo pipefail
bash ci/jenkins/tests/run-all.sh
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ output
_build-*/**
*.log
.worktrees/

*.txt

docs/superpowers/
69 changes: 20 additions & 49 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -227,15 +227,25 @@ gh release upload "$release_tag" "$MANIFEST_FILE" --clobber
}

post {
success {
always {
archiveArtifacts artifacts: 'ci/jenkins/build/*', allowEmptyArchive: true
script {
def result = (currentBuild.currentResult ?: 'SUCCESS').toUpperCase()
env.N8N_STATUS = result == 'SUCCESS' ? 'success' : 'failure'
env.N8N_ERROR_SUMMARY = result == 'SUCCESS' ? '' : 'Pipeline failed before completion.'
}
withCredentials([
string(credentialsId: 'n8n-webhook-url', variable: 'WEBHOOK_URL'),
string(credentialsId: 'n8n-webhook-token', variable: 'N8N_WEBHOOK_SHARED_TOKEN')
Comment thread
ericrocha97 marked this conversation as resolved.
]) {
sh '''#!/usr/bin/env bash
set -euo pipefail

published_tags="$(paste -sd, "$TAGS_FILE")"
published_tags=""
if [[ -f "$TAGS_FILE" ]]; then
published_tags="$(paste -sd, "$TAGS_FILE")"
fi

finished_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
build_started_at="${BUILD_STARTED_AT:-}"
if [[ -z "$build_started_at" && -f ci/jenkins/build/started_at ]]; then
Expand All @@ -260,68 +270,29 @@ finished_epoch="$(date -u -d "$finished_at" +%s 2>/dev/null || printf '0')"
duration_ms="$(( (finished_epoch - started_epoch) * 1000 ))"
if (( duration_ms < 0 )); then duration_ms=0; fi

export STATUS="success"
export STATUS="${N8N_STATUS:-failure}"
export JOB_NAME="$JOB_NAME"
export BUILD_NUMBER="$BUILD_NUMBER"
export BUILD_URL="$BUILD_URL"
git_sha="${GIT_COMMIT:-${GIT_PREVIOUS_SUCCESSFUL_COMMIT:-unknown}}"
export GIT_SHA="$git_sha"
export IMAGE_NAME="$IMAGE_REPOSITORY"
export PUBLISHED_TAGS="${published_tags:-$short_date}"
if [[ "$STATUS" == "success" ]]; then
export PUBLISHED_TAGS="${published_tags:-$short_date}"
else
export PUBLISHED_TAGS=""
fi
export TIMESTAMP_UTC="$finished_at"
export ERROR_SUMMARY=""
export ERROR_SUMMARY="${N8N_ERROR_SUMMARY:-}"
export STARTED_AT="$build_started_at"
export FINISHED_AT="$finished_at"
export DURATION_MS="$duration_ms"
export RELEASE_TAG="${release_tag:-unknown}"
if ! bash ci/jenkins/scripts/notify_n8n.sh; then
echo "WARN: notify_n8n.sh failed in post-success hook (best-effort notification)." >&2
fi
'''
}
}
failure {
withCredentials([
string(credentialsId: 'n8n-webhook-url', variable: 'WEBHOOK_URL'),
string(credentialsId: 'n8n-webhook-token', variable: 'N8N_WEBHOOK_SHARED_TOKEN')
]) {
sh '''#!/usr/bin/env bash
set -euo pipefail

finished_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
started_at="${BUILD_STARTED_AT:-}"
if [[ -z "$started_at" && -f ci/jenkins/build/started_at ]]; then
started_at="$(<ci/jenkins/build/started_at)"
fi
if [[ -z "$started_at" ]]; then
started_at="$finished_at"
fi
started_epoch="$(date -u -d "$started_at" +%s 2>/dev/null || printf '0')"
finished_epoch="$(date -u -d "$finished_at" +%s 2>/dev/null || printf '0')"
duration_ms="$(( (finished_epoch - started_epoch) * 1000 ))"
if (( duration_ms < 0 )); then duration_ms=0; fi

export STATUS="failure"
export JOB_NAME="$JOB_NAME"
export BUILD_NUMBER="$BUILD_NUMBER"
export BUILD_URL="$BUILD_URL"
export GIT_SHA="${GIT_COMMIT:-unknown}"
export IMAGE_NAME="$IMAGE_REPOSITORY"
export PUBLISHED_TAGS=""
export TIMESTAMP_UTC="$finished_at"
export ERROR_SUMMARY="Pipeline failed before completion."
export STARTED_AT="$started_at"
export FINISHED_AT="$finished_at"
export DURATION_MS="$duration_ms"
export RELEASE_TAG="${RELEASE_TAG:-unknown}"
if ! bash ci/jenkins/scripts/notify_n8n.sh; then
echo "WARN: notify_n8n.sh failed in post-failure hook (best-effort notification)." >&2
echo "WARN: notify_n8n.sh failed in post hook (best-effort notification)." >&2
fi
'''
}
}
always {
archiveArtifacts artifacts: 'ci/jenkins/build/*', allowEmptyArchive: true
}
}
}
42 changes: 19 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This project was created using the finpilot template: <https://github.com/projec

Portuguese version: [README.pt-BR.md](README.pt-BR.md)

It builds a custom bootc image based on Bluefin DX, using the multi-stage OCI pattern from the Bluefin ecosystem.
It builds a COSMIC-only custom bootc image based on Bluefin DX, using the multi-stage OCI pattern from the Bluefin ecosystem.

## Build and Publish

Expand Down Expand Up @@ -38,7 +38,9 @@ Here are the changes from Bluefin DX. This image is based on Bluefin and include

### Removed/Disabled

- None.
- **GNOME desktop session**: Removed so COSMIC is the only login session.
- **GDM**: Disabled/removed in favor of COSMIC Greeter.
- **GNOME-specific mutter tuning**: Removed because GNOME is no longer shipped as a desktop session.

### System Optimizations (CachyOS/LinuxToys)

Expand All @@ -49,30 +51,31 @@ Here are the changes from Bluefin DX. This image is based on Bluefin and include
- **journald**: Journal size limited to 50MB
- **earlyoom**: 5% memory/swap threshold, D-Bus notifications
- **Auto-updates**: rpm-ostreed AutomaticUpdatePolicy=stage
- **GNOME**: mutter check-alive-timeout set to 20s
- **Fastfetch**: Custom config showing image name/version, COSMIC version, and build date (overrides upstream Bluefin config)

### Configuration Changes

- Dual desktop sessions available in GDM (GNOME and COSMIC).
- COSMIC Greeter is enabled as the default login manager.
- COSMIC is the only desktop session presented at login.
- Custom ujust commands available: install-nvm, install-sdkman, install-dev-managers.

*Last updated: 2026-03-14*
*Last updated: 2026-04-24*

## What is this image

bluefin-cosmic-dx is a developer-focused Bluefin image with **GNOME + COSMIC dual desktop** support. You can choose which desktop environment to use at the login screen.
bluefin-cosmic-dx is a developer-focused Bluefin DX image that keeps the Bluefin DX base and ships COSMIC as the only desktop environment.

## What changes in this version

Based on **Bluefin DX**, this image adds:
Based on **Bluefin DX**, this image adds and changes:

- **COSMIC desktop** (System76) as an alternative to GNOME
- **COSMIC desktop** (System76) as the only desktop session
- **COSMIC Greeter** as the login manager
- **GNOME desktop session removed** from the final image
- **VSCode Insiders** installed via RPM
- **Warp Terminal** installed via RPM
- **Vicinae** installed via Terra repo (Bazzite-compatible)
- **Dual desktop support**: Choose GNOME or COSMIC at login (GDM)
- All Bluefin DX features (containers, DevPods, CLI tools, etc.)
- All Bluefin DX development features that remain compatible with the COSMIC-only desktop target

Base image: `ghcr.io/ublue-os/bluefin-dx:stable-daily`

Expand Down Expand Up @@ -164,20 +167,17 @@ Image signing is optional. The repository keeps Cosign signing steps in `.github

If you decide to re-enable GitHub Actions release builds later, these signing steps can be reactivated there. For the current production flow, Jenkins is responsible for build/publish.

## Choosing Desktop at Login
## COSMIC Login

At the GDM login screen, click the **⚙️ gear icon** to select:

- **GNOME** - Default Bluefin desktop
- **COSMIC** - System76's new desktop environment
The image boots to COSMIC Greeter and starts the COSMIC Wayland session. GNOME is intentionally not offered as a login option.

## Troubleshooting

### COSMIC session does not appear in GDM
### COSMIC session does not appear

1. Verify packages: `rpm -qa | grep -i cosmic`
2. Check session file: `ls /usr/share/wayland-sessions/cosmic.desktop`
3. Restart GDM: `sudo systemctl restart gdm`
3. Check COSMIC Greeter: `systemctl status cosmic-greeter`

### VSCode or Warp fails to start

Expand All @@ -200,16 +200,12 @@ At the GDM login screen, click the **⚙️ gear icon** to select:
<details>
<summary>View screenshots</summary>

### GDM session selector
### COSMIC Greeter

![GDM session selector](https://raw.githubusercontent.com/ericrocha97/bluefin/main/docs/images/gdm-selector.png)
![COSMIC Greeter](https://raw.githubusercontent.com/ericrocha97/bluefin/main/docs/images/cosmic-greeter.png)

### COSMIC desktop

![COSMIC desktop](https://raw.githubusercontent.com/ericrocha97/bluefin/main/docs/images/cosmic-desktop.png)

### GNOME desktop

![GNOME desktop](https://raw.githubusercontent.com/ericrocha97/bluefin/main/docs/images/gnome-desktop.png)

</details>
42 changes: 19 additions & 23 deletions README.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Este projeto foi criado usando o template finpilot: <https://github.com/projectb

Versão em inglês: [README.md](README.md)

Ele constrói uma imagem bootc customizada baseada no Bluefin DX, usando o padrão multi-stage OCI do ecossistema Bluefin.
Ele constrói uma imagem bootc customizada COSMIC-only baseada no Bluefin DX, usando o padrão multi-stage OCI do ecossistema Bluefin.

## Build e Publicação

Expand Down Expand Up @@ -38,7 +38,9 @@ Aqui estão as mudanças em relação ao Bluefin DX. Esta imagem é baseada no B

### Removidos/Desativados

- Nenhum.
- **Sessão GNOME**: Removida para que COSMIC seja a única sessão de login.
- **GDM**: Desativado/removido em favor do COSMIC Greeter.
- **Tuning específico do mutter/GNOME**: Removido porque GNOME não é mais enviado como sessão desktop.

### Otimizações do Sistema (CachyOS/LinuxToys)

Expand All @@ -49,30 +51,31 @@ Aqui estão as mudanças em relação ao Bluefin DX. Esta imagem é baseada no B
- **journald**: Tamanho do journal limitado a 50MB
- **earlyoom**: Threshold de 5% memória/swap, notificações D-Bus
- **Auto-updates**: rpm-ostreed AutomaticUpdatePolicy=stage
- **GNOME**: mutter check-alive-timeout configurado para 20s
- **Fastfetch**: Config customizado exibindo nome/versão da imagem, versão do COSMIC e data do build (sobrescreve config padrão do Bluefin)

### Mudanças de configuração

- Sessões de desktop duplas disponíveis no GDM (GNOME e COSMIC).
- COSMIC Greeter é habilitado como gerenciador de login padrão.
- COSMIC é a única sessão de desktop apresentada no login.
- Comandos customizados do ujust disponíveis: install-nvm, install-sdkman, install-dev-managers.

*Última atualização: 2026-03-14*
*Última atualização: 2026-04-24*

## O que é esta imagem

bluefin-cosmic-dx é uma imagem Bluefin focada em desenvolvimento, com **suporte a GNOME + COSMIC dual desktop**. Você pode escolher qual ambiente usar na tela de login.
bluefin-cosmic-dx é uma imagem Bluefin DX focada em desenvolvimento que mantém a base Bluefin DX e entrega COSMIC como o único ambiente desktop.

## O que muda nesta versão

Baseado no **Bluefin DX**, esta imagem adiciona:
Baseado no **Bluefin DX**, esta imagem adiciona e altera:

- **Desktop COSMIC** (System76) como alternativa ao GNOME
- **Desktop COSMIC** (System76) como única sessão de desktop
- **COSMIC Greeter** como gerenciador de login
- **Sessão GNOME removida** da imagem final
- **VSCode Insiders** instalado via RPM
- **Warp Terminal** instalado via RPM
- **Vicinae** instalado via repo Terra (compatível com Bazzite)
- **Suporte dual desktop**: Escolha GNOME ou COSMIC no login (GDM)
- Todos os recursos do Bluefin DX (containers, DevPods, ferramentas CLI, etc.)
- Recursos de desenvolvimento do Bluefin DX que continuam compatíveis com o alvo COSMIC-only

Imagem base: `ghcr.io/ublue-os/bluefin-dx:stable-daily`

Expand Down Expand Up @@ -160,20 +163,17 @@ A assinatura de imagem é opcional. O repositório mantém etapas de assinatura

Se no futuro você reativar build de release no GitHub Actions, essas etapas de assinatura podem ser usadas lá novamente. No fluxo atual de produção, o Jenkins é responsável por build/publicação.

## Escolhendo o Desktop no Login
## Login COSMIC

Na tela de login (GDM), clique no **ícone de engrenagem ⚙️** para selecionar:

- **GNOME** - Desktop padrão do Bluefin
- **COSMIC** - Novo ambiente desktop da System76
A imagem inicia no COSMIC Greeter e abre a sessão Wayland do COSMIC. GNOME intencionalmente não é oferecido como opção de login.

## Solução de problemas

### Sessão COSMIC não aparece no GDM
### Sessão COSMIC não aparece

1. Verifique pacotes: `rpm -qa | grep -i cosmic`
2. Verifique o arquivo de sessão: `ls /usr/share/wayland-sessions/cosmic.desktop`
3. Reinicie o GDM: `sudo systemctl restart gdm`
3. Verifique o COSMIC Greeter: `systemctl status cosmic-greeter`

### VSCode ou Warp não abre

Expand All @@ -196,16 +196,12 @@ Na tela de login (GDM), clique no **ícone de engrenagem ⚙️** para seleciona
<details>
<summary>Ver screenshots</summary>

### Seletor de sessão no GDM
### COSMIC Greeter

![Seletor de sessão no GDM](https://raw.githubusercontent.com/ericrocha97/bluefin/main/docs/images/gdm-selector.png)
![COSMIC Greeter](https://raw.githubusercontent.com/ericrocha97/bluefin/main/docs/images/cosmic-greeter.png)

### Desktop COSMIC

![Desktop COSMIC](https://raw.githubusercontent.com/ericrocha97/bluefin/main/docs/images/cosmic-desktop.png)

### Desktop GNOME

![Desktop GNOME](https://raw.githubusercontent.com/ericrocha97/bluefin/main/docs/images/gnome-desktop.png)

</details>
20 changes: 0 additions & 20 deletions build/15-system-optimizations.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ set -eoux pipefail
# - journald size limits
# - rpm-ostreed automatic update policy
# - earlyoom configuration
# - GNOME mutter check-alive-timeout
###############################################################################

# Source helper functions
Expand Down Expand Up @@ -106,24 +105,6 @@ log_success "earlyoom service enabled"

echo "::endgroup::"

###############################################################################
# Install GNOME GSettings Override
###############################################################################

echo "::group:: Install GNOME Tweaks"
log_step "Installing GNOME GSettings overrides..."

mkdir -p /usr/share/glib-2.0/schemas/
cp -v "${SYSTEM_FILES_DIR}"/usr/share/glib-2.0/schemas/99-custom.gschema.override \
/usr/share/glib-2.0/schemas/

# Recompile GSettings schemas to apply overrides
log_info "Recompiling GSettings schemas..."
glib-compile-schemas /usr/share/glib-2.0/schemas/
log_success "GNOME check-alive-timeout set to 20000ms"

echo "::endgroup::"

###############################################################################
# Install Custom Fastfetch Configuration
###############################################################################
Expand Down Expand Up @@ -156,5 +137,4 @@ log_info " ✓ Transparent Huge Pages (defer+madvise, shrinker at 80%)"
log_info " ✓ Journal size limited to 50MB"
log_info " ✓ Automatic updates (stage policy)"
log_info " ✓ earlyoom enabled (5% memory/swap threshold)"
log_info " ✓ GNOME mutter check-alive-timeout = 20s"
log_info " ✓ Custom fastfetch config (image info, COSMIC version, build date)"
Loading
Loading