Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b8292aa
local: devcontainer
parkan Sep 19, 2025
856acd8
postgres
parkan Sep 19, 2025
874a93e
no password
parkan Sep 19, 2025
57c487f
mysql
parkan Sep 19, 2025
f4764fa
mysql manual start?
parkan Sep 19, 2025
042a0c2
updates and perms
parkan Sep 19, 2025
17c8546
restore changes
parkan Sep 19, 2025
4440bac
more restore
parkan Sep 19, 2025
504fd45
fix passwords
parkan Sep 19, 2025
e1e5514
hopefully fix DB craziness
parkan Sep 19, 2025
b17019c
finally actually fix the DB
parkan Sep 20, 2025
7c7d282
devcontainer based tests
parkan Sep 22, 2025
45815df
workaround for https://github.com/devcontainers/ci/issues/375
parkan Sep 24, 2025
8091652
try a more universal relabel?
parkan Sep 24, 2025
f8ac1ac
simplify and generalize
parkan Sep 24, 2025
4b93bee
move podman specific stuff out entirely
parkan Sep 24, 2025
4eff086
try 1:1 podman run
parkan Sep 25, 2025
ba37840
kill docker with fire
parkan Sep 25, 2025
cb509c8
use my podman-docker action
parkan Sep 26, 2025
269fffb
drop linuxbrewed mysql, user scope psql
parkan Sep 26, 2025
97979cb
missing files
parkan Sep 26, 2025
2bf7a3c
perms
parkan Sep 26, 2025
649a873
noninteractive sudo
parkan Sep 26, 2025
7375d6d
meticulously re-engineer the devcontainer
parkan Oct 2, 2025
ea753e4
small workflow fix
parkan Oct 2, 2025
4b02c14
revert
parkan Oct 2, 2025
c4fdf02
fix mysql user
parkan Oct 2, 2025
5117de4
fix mysql fully
parkan Oct 3, 2025
6b6445f
final (?) fixes for DB connectivity!
parkan Oct 3, 2025
97954bd
add create db role
parkan Oct 3, 2025
20c95cf
ok we have working DB tests
parkan Oct 3, 2025
7dbb93f
fix job selection logic
parkan Oct 14, 2025
45eda3d
suppress missing table noise in tests
parkan Oct 14, 2025
7280200
disable DAG generation during duplicate piece test
parkan Oct 14, 2025
cbc6cb2
resolve 'record changed since last read' errors
parkan Oct 14, 2025
50f0434
use v2 action, remove stray file
parkan Oct 14, 2025
71e0bb6
reorder steps for fast fail
parkan Oct 14, 2025
7fee74d
add steps that make sense
parkan Oct 14, 2025
249cab7
remove heavyweight unified workflows
Oct 15, 2025
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
36 changes: 36 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
ARG GO_VERSION=1.24
ARG DEBIAN_CODENAME=trixie

FROM mcr.microsoft.com/devcontainers/go:${GO_VERSION}-${DEBIAN_CODENAME}

ARG PG_MAJOR=16
ARG MARIADB_MAJOR=12.0.2

USER root

# Add PostgreSQL and MariaDB official repositories (detect codename from /etc/os-release)
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
wget ca-certificates gnupg curl \
&& wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg \
&& echo "deb http://apt.postgresql.org/pub/repos/apt $(. /etc/os-release && echo $VERSION_CODENAME)-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& curl -LsSO https://r.mariadb.com/downloads/mariadb_repo_setup \
&& chmod +x mariadb_repo_setup \
&& ./mariadb_repo_setup --mariadb-server-version="mariadb-${MARIADB_MAJOR}" --skip-maxscale --skip-tools \
&& rm -f mariadb_repo_setup \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
postgresql-${PG_MAJOR} postgresql-client-${PG_MAJOR} \
mariadb-server mariadb-client \
&& rm -rf /var/lib/apt/lists/*

# Prepare user-owned data dirs for rootless startup
RUN mkdir -p /home/vscode/.local/share/pg/pgdata \
&& mkdir -p /home/vscode/.local/share/mysql \
&& chown -R vscode:vscode /home/vscode/.local/share

# Set environment variables based on build args
ENV PG_BIN_DIR=/usr/lib/postgresql/${PG_MAJOR}/bin

USER vscode

45 changes: 45 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "singularity",
"build": {
"dockerfile": "Dockerfile",
"args": {
"GO_VERSION": "1.24",
"DEBIAN_CODENAME": "trixie",
"PG_MAJOR": "16",
"MARIADB_MAJOR": "12.0.2"
}
},
"customizations": {
"vscode": {
"extensions": [
"golang.go",
"eamodio.gitlens"
],
"settings": {
"go.useLanguageServer": true,
"go.toolsEnvVars": {
"GOPATH": "/home/vscode/go"
}
}
}
},
"forwardPorts": [],
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/singularity,type=bind,consistency=cached,relabel=private",
"workspaceFolder": "/workspaces/singularity",
"postCreateCommand": "/bin/bash -lc '${containerWorkspaceFolder}/.devcontainer/post-create.sh'",
"postStartCommand": "/bin/bash -lc '${containerWorkspaceFolder}/.devcontainer/start-postgres.sh && ${containerWorkspaceFolder}/.devcontainer/start-mysql.sh'",
"remoteUser": "vscode",
"containerEnv": {
"GOPATH": "/home/vscode/go",
"MYSQL_DATABASE": "singularity",
"MYSQL_USER": "singularity",
"MYSQL_PASSWORD": "singularity",
"MYSQL_SOCKET": "/home/vscode/.local/share/mysql/mysql.sock",
"PGDATA": "/home/vscode/.local/share/pg/pgdata",
"PGPORT": "55432",
"PGSOCK_DIR": "/home/vscode/.local/share/pg"
},
"runArgs": ["--userns=keep-id"],
"containerUser": "vscode"
}

55 changes: 55 additions & 0 deletions .devcontainer/init-mysql.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euo pipefail

# MariaDB client is required for init

# Resolve socket path; default to user-owned socket
SOCKET="${MYSQL_SOCKET:-${HOME}/.local/share/mysql/mysql.sock}"

## Removed one-time init guard; operations below are idempotent

# Determine root auth flags
MYSQL_ROOT_FLAGS=("-uroot")
if [ -n "${MYSQL_ROOT_PASSWORD:-}" ]; then
MYSQL_ROOT_FLAGS+=("-p${MYSQL_ROOT_PASSWORD}")
fi

# Wait for server readiness (best effort)
echo "Waiting for MySQL server at socket: $SOCKET"
for i in {1..60}; do
if mariadb-admin --socket="$SOCKET" ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then
echo "MySQL server is ready for init"
break
fi
sleep 1
done

# Bail if still unreachable
if ! mariadb-admin --socket="$SOCKET" ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then
echo "MySQL server not reachable, init failed"
exit 1
fi

# Create database and user idempotently (MySQL 8+ supports IF NOT EXISTS for users)
DB=${MYSQL_DATABASE:-singularity}
USER=${MYSQL_USER:-singularity}
PASS=${MYSQL_PASSWORD:-singularity}

echo "Creating database and user: ${USER}@localhost and ${USER}@%"
mariadb --socket="$SOCKET" "${MYSQL_ROOT_FLAGS[@]}" <<SQL
CREATE DATABASE IF NOT EXISTS \`${DB}\`;
CREATE USER IF NOT EXISTS '${USER}'@'localhost' IDENTIFIED BY '${PASS}';
CREATE USER IF NOT EXISTS '${USER}'@'%' IDENTIFIED BY '${PASS}';
-- tests create per-run databases, so grant global privileges for dev only
GRANT ALL PRIVILEGES ON *.* TO '${USER}'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO '${USER}'@'%' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON \`${DB}\`.* TO '${USER}'@'localhost';
GRANT ALL PRIVILEGES ON \`${DB}\`.* TO '${USER}'@'%';
FLUSH PRIVILEGES;
SQL

echo "MySQL init completed successfully"

## No marker file; script can run safely on every start


55 changes: 55 additions & 0 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euo pipefail

# Initialize Go modules
go mod download

chmod +x .devcontainer/*.sh || true

# Initialize database systems
echo "Setting up databases..."

# Create data directories
mkdir -p /home/vscode/.local/share/pg/pgdata /home/vscode/.local/share/pg /home/vscode/.local/share/mysql/data /home/vscode/.local/share/mysql

# Initialize Postgres
if [ ! -f "/home/vscode/.local/share/pg/pgdata/PG_VERSION" ]; then
echo "Initializing Postgres..."
/usr/lib/postgresql/16/bin/initdb -D /home/vscode/.local/share/pg/pgdata --auth trust --auth-local trust --auth-host trust
echo "listen_addresses='localhost'" >> /home/vscode/.local/share/pg/pgdata/postgresql.conf
{
echo 'host all all 127.0.0.1/32 trust'
echo 'host all all ::1/128 trust'
echo 'local all all trust'
} >> /home/vscode/.local/share/pg/pgdata/pg_hba.conf
fi

# Initialize MariaDB
if [ ! -d "/home/vscode/.local/share/mysql/data/mysql" ]; then
echo "Initializing MariaDB..."
mariadb-install-db --datadir=/home/vscode/.local/share/mysql/data --auth-root-authentication-method=normal --skip-test-db >/dev/null
fi

# Start both servers
echo "Starting database servers..."
.devcontainer/start-postgres.sh
.devcontainer/start-mysql.sh

# Create users (databases will be created during testing as needed)
echo "Creating database users..."

# Postgres setup
psql -h localhost -p 55432 -d postgres -c "CREATE USER singularity WITH SUPERUSER CREATEDB CREATEROLE LOGIN;"

# MySQL setup
mariadb --socket=/home/vscode/.local/share/mysql/mysql.sock -uroot <<SQL
CREATE USER 'singularity'@'localhost' IDENTIFIED BY 'singularity';
CREATE USER 'singularity'@'%' IDENTIFIED BY 'singularity';
GRANT ALL PRIVILEGES ON *.* TO 'singularity'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'singularity'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
SQL

echo "Database setup completed successfully"


46 changes: 46 additions & 0 deletions .devcontainer/start-mysql.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
set -euo pipefail

# MariaDB server configuration
MYSQL_BASE="${HOME}/.local/share/mysql"
DATA_DIR="${MYSQL_BASE}/data"
SOCKET="${MYSQL_SOCKET:-${MYSQL_BASE}/mysql.sock}"
PID_FILE="${MYSQL_BASE}/mysql.pid"
PORT="${MYSQL_PORT:-3306}"
LOG_FILE="${MYSQL_BASE}/mysql.err"

# Check if already running
if [ -S "${SOCKET}" ] && mariadb-admin --socket="${SOCKET}" ping >/dev/null 2>&1; then
echo "MySQL already running"
exit 0
fi

# Start MariaDB server
echo "Starting MySQL server"
touch "${LOG_FILE}"
nohup mariadbd \
--datadir="${DATA_DIR}" \
--socket="${SOCKET}" \
--pid-file="${PID_FILE}" \
--bind-address=127.0.0.1 \
--port="${PORT}" \
--skip-name-resolve \
--log-error="${LOG_FILE}" \
>/dev/null 2>&1 &

# Wait for MySQL to be ready
for i in {1..60}; do
if [ -S "${SOCKET}" ] && grep -q "ready for connections" "${LOG_FILE}" >/dev/null 2>&1; then
echo "MySQL server is ready"
exit 0
fi
sleep 1
done

echo "MySQL server failed to start"
if [ -f "${LOG_FILE}" ]; then
echo "--- Begin MariaDB error log ---"
tail -n 200 "${LOG_FILE}" || true
echo "--- End MariaDB error log ---"
fi
exit 1
21 changes: 21 additions & 0 deletions .devcontainer/start-postgres.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail

# Postgres server configuration
PGDATA_DIR="${PGDATA:-/home/vscode/.local/share/pg/pgdata}"
LOG_FILE="${PGDATA_DIR}/postgres.log"
PGSOCK_DIR="${PGSOCK_DIR:-/home/vscode/.local/share/pg}"
PGPORT="${PGPORT:-55432}"
PG_BIN_DIR="${PG_BIN_DIR:-/usr/lib/postgresql/16/bin}"

# Check if already running
if "${PG_BIN_DIR}/pg_ctl" -D "$PGDATA_DIR" status >/dev/null 2>&1; then
echo "Postgres already running"
exit 0
fi

# Start Postgres server
echo "Starting Postgres server"
"${PG_BIN_DIR}/pg_ctl" -D "$PGDATA_DIR" -l "$LOG_FILE" -w -o "-p ${PGPORT} -k ${PGSOCK_DIR}" start


94 changes: 94 additions & 0 deletions .github/workflows/devcontainer-podman.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
name: CI (Podman Devcontainer)

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }}
cancel-in-progress: true

jobs:
devcontainer-checks:
name: Devcontainer CI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Podman as Docker
uses: parkan/github-actions/setup-podman-docker@v2
with:
disable-docker: true
cache-storage: false # Disabled until cache issues resolved

- name: Build devcontainer
id: build
uses: parkan/github-actions/devcontainer-build@v2
with:
workspace-folder: .
container-runtime: podman
container-id-label: ci=podman

# Fast surface checks and codegen first
- name: Generate swagger code
uses: parkan/github-actions/devcontainer-exec@v2
with:
container-id: ${{ steps.build.outputs.container-id }}
command: 'cd /workspaces/singularity && mkdir -p client/swagger/client && go install github.com/go-swagger/go-swagger/cmd/[email protected] && go generate ./client/swagger/...'
container-runtime: podman

- name: Check formatting
uses: parkan/github-actions/devcontainer-exec@v2
with:
container-id: ${{ steps.build.outputs.container-id }}
command: 'cd /workspaces/singularity && gofmt -l .'
container-runtime: podman

- name: Run go vet
uses: parkan/github-actions/devcontainer-exec@v2
with:
container-id: ${{ steps.build.outputs.container-id }}
command: 'cd /workspaces/singularity && go vet ./...'
container-runtime: podman

- name: Run staticcheck
uses: parkan/github-actions/devcontainer-exec@v2
with:
container-id: ${{ steps.build.outputs.container-id }}
command: 'cd /workspaces/singularity && staticcheck ./...'
container-runtime: podman

- name: Build binary
uses: parkan/github-actions/devcontainer-exec@v2
with:
container-id: ${{ steps.build.outputs.container-id }}
command: 'cd /workspaces/singularity && go build -o singularity .'
container-runtime: podman

- name: Run tests
uses: parkan/github-actions/devcontainer-exec@v2
with:
container-id: ${{ steps.build.outputs.container-id }}
command: 'cd /workspaces/singularity && go test -v ./...'
container-runtime: podman

- name: Run integration tests
uses: parkan/github-actions/devcontainer-exec@v2
with:
container-id: ${{ steps.build.outputs.container-id }}
command: 'cd /workspaces/singularity && SINGULARITY_TEST_INTEGRATION=true go test -v -timeout 20m -run "Integration" ./cmd/...'
container-runtime: podman

- name: Cleanup
if: always()
uses: parkan/github-actions/devcontainer-cleanup@v2
with:
container-id: ${{ steps.build.outputs.container-id }}
container-runtime: podman
3 changes: 0 additions & 3 deletions .github/workflows/go-check-config.json

This file was deleted.

35 changes: 0 additions & 35 deletions .github/workflows/go-check.yml

This file was deleted.

Loading