From b8292aafc23d431be3a08ae8430210a4e9bdb33f Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 19 Sep 2025 13:05:24 +0000 Subject: [PATCH 01/39] local: devcontainer --- .devcontainer/devcontainer.json | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..63a4af4d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,37 @@ +{ + "name": "singularity", + "image": "mcr.microsoft.com/devcontainers/go:1.24", + "customizations": { + "vscode": { + "extensions": [ + "golang.go", + "eamodio.gitlens" + ], + "settings": { + "go.useLanguageServer": true, + "go.toolsEnvVars": { + "GOPATH": "/home/vscode/go" + } + } + } + }, + "features": { + "ghcr.io/devcontainers/features/go:1": { + "version": "1.24" + }, + "ghcr.io/itsmechlark/features/postgresql:1": { + "version": "16" + } + }, + "forwardPorts": [], + "postCreateCommand": "go mod download", + "postStartCommand": "/bin/bash -lc 'set -e; if command -v pg_isready >/dev/null 2>&1; then for i in $(seq 1 30); do pg_isready -q && break || sleep 1; done; psql -U postgres -d postgres -c \"CREATE ROLE singularity WITH LOGIN SUPERUSER PASSWORD '\\''singularity'\\''';\" >/dev/null 2>&1 || true; psql -U postgres -d postgres -tc \"SELECT 1 FROM pg_database WHERE datname = '\\''singularity'\\''\" | grep -q 1 || createdb -U postgres singularity; fi'", + "remoteUser": "vscode", + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached,relabel=private", + "workspaceFolder": "/workspace", + "containerEnv": { + "GOPATH": "/home/vscode/go" + }, + "runArgs": ["--userns=keep-id"], + "containerUser": "vscode" +} From 856acd85952f62d8aeeb068ed53e9457cf1ac2fb Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 19 Sep 2025 13:20:05 +0000 Subject: [PATCH 02/39] postgres --- .devcontainer/devcontainer.json | 2 +- .devcontainer/init-postgres.sh | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100755 .devcontainer/init-postgres.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 63a4af4d..e4286a2e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -25,7 +25,7 @@ }, "forwardPorts": [], "postCreateCommand": "go mod download", - "postStartCommand": "/bin/bash -lc 'set -e; if command -v pg_isready >/dev/null 2>&1; then for i in $(seq 1 30); do pg_isready -q && break || sleep 1; done; psql -U postgres -d postgres -c \"CREATE ROLE singularity WITH LOGIN SUPERUSER PASSWORD '\\''singularity'\\''';\" >/dev/null 2>&1 || true; psql -U postgres -d postgres -tc \"SELECT 1 FROM pg_database WHERE datname = '\\''singularity'\\''\" | grep -q 1 || createdb -U postgres singularity; fi'", + "postStartCommand": "/bin/bash -lc '/workspace/.devcontainer/init-postgres.sh'", "remoteUser": "vscode", "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached,relabel=private", "workspaceFolder": "/workspace", diff --git a/.devcontainer/init-postgres.sh b/.devcontainer/init-postgres.sh new file mode 100755 index 00000000..af88ceee --- /dev/null +++ b/.devcontainer/init-postgres.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -euo pipefail + +# If postgres isn't present in this image, exit quietly +if ! command -v pg_isready >/dev/null 2>&1; then + exit 0 +fi + +# Wait for server readiness (best effort) +for i in {1..60}; do + if pg_isready -q; then + break + fi + sleep 1 +done + +# If we still can't connect, bail (container may not include a running server) +if ! psql -U postgres -d postgres -tc "SELECT 1" >/dev/null 2>&1; then + exit 0 +fi + +# Create role if missing (idempotent) +psql -U postgres -d postgres -v ON_ERROR_STOP=1 -c "DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'singularity') THEN CREATE ROLE singularity WITH LOGIN SUPERUSER PASSWORD 'singularity'; END IF; END $$;" + +# Create database if missing (idempotent) +if ! psql -U postgres -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = 'singularity'" | grep -q 1; then + createdb -U postgres singularity +fi + + From 874a93ee8a62b615912336df4d625ee163b9c254 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 19 Sep 2025 13:22:36 +0000 Subject: [PATCH 03/39] no password --- .devcontainer/init-postgres.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.devcontainer/init-postgres.sh b/.devcontainer/init-postgres.sh index af88ceee..6c8319e6 100755 --- a/.devcontainer/init-postgres.sh +++ b/.devcontainer/init-postgres.sh @@ -15,16 +15,16 @@ for i in {1..60}; do done # If we still can't connect, bail (container may not include a running server) -if ! psql -U postgres -d postgres -tc "SELECT 1" >/dev/null 2>&1; then +if ! PGPASSWORD="" psql --no-password -U postgres -d postgres -tc "SELECT 1" >/dev/null 2>&1; then exit 0 fi # Create role if missing (idempotent) -psql -U postgres -d postgres -v ON_ERROR_STOP=1 -c "DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'singularity') THEN CREATE ROLE singularity WITH LOGIN SUPERUSER PASSWORD 'singularity'; END IF; END $$;" +PGPASSWORD="" psql --no-password -U postgres -d postgres -v ON_ERROR_STOP=1 -c "DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'singularity') THEN CREATE ROLE singularity WITH LOGIN SUPERUSER PASSWORD 'singularity'; END IF; END $$;" # Create database if missing (idempotent) -if ! psql -U postgres -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = 'singularity'" | grep -q 1; then - createdb -U postgres singularity +if ! PGPASSWORD="" psql --no-password -U postgres -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = 'singularity'" | grep -q 1; then + PGPASSWORD="" createdb --no-password -U postgres singularity fi From 57c487f9398255f075e63867d30c9b2ac889ddee Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 19 Sep 2025 14:17:14 +0000 Subject: [PATCH 04/39] mysql --- .devcontainer/devcontainer.json | 11 ++++++--- .devcontainer/init-mysql.sh | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) create mode 100755 .devcontainer/init-mysql.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e4286a2e..dc423416 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -21,17 +21,22 @@ }, "ghcr.io/itsmechlark/features/postgresql:1": { "version": "16" - } + }, + "ghcr.io/devcontainers-extra/features/mysql-homebrew:1": {} }, "forwardPorts": [], "postCreateCommand": "go mod download", - "postStartCommand": "/bin/bash -lc '/workspace/.devcontainer/init-postgres.sh'", + "postStartCommand": "/bin/bash -lc '/workspace/.devcontainer/init-postgres.sh && /workspace/.devcontainer/init-mysql.sh'", "remoteUser": "vscode", "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached,relabel=private", "workspaceFolder": "/workspace", "containerEnv": { - "GOPATH": "/home/vscode/go" + "GOPATH": "/home/vscode/go", + "MYSQL_DATABASE": "singularity", + "MYSQL_USER": "singularity", + "MYSQL_PASSWORD": "singularity" }, "runArgs": ["--userns=keep-id"], "containerUser": "vscode" } + diff --git a/.devcontainer/init-mysql.sh b/.devcontainer/init-mysql.sh new file mode 100755 index 00000000..75631f75 --- /dev/null +++ b/.devcontainer/init-mysql.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -euo pipefail + +# If mysql client isn't present, exit quietly +if ! command -v mysql >/dev/null 2>&1; then + exit 0 +fi + +# 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) +for i in {1..60}; do + if mysqladmin ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then + break + fi + sleep 1 +done + +# Bail if still unreachable +if ! mysqladmin ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then + exit 0 +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} + +mysql "${MYSQL_ROOT_FLAGS[@]}" < Date: Fri, 19 Sep 2025 14:31:48 +0000 Subject: [PATCH 05/39] mysql manual start? --- .devcontainer/start-mysql.sh | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .devcontainer/start-mysql.sh diff --git a/.devcontainer/start-mysql.sh b/.devcontainer/start-mysql.sh new file mode 100644 index 00000000..fe5faf46 --- /dev/null +++ b/.devcontainer/start-mysql.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Paths (homebrew mysql in devcontainer) +MYSQLD="${MYSQLD:-/home/linuxbrew/.linuxbrew/opt/mysql/bin/mysqld}" +MYSQLADMIN="${MYSQLADMIN:-/home/linuxbrew/.linuxbrew/bin/mysqladmin}" + +# Runtime locations inside workspace (owned by repo user) +DATADIR="${MYSQL_DATADIR:-/workspace/.devcontainer/.mysql-data}" +SOCKET="${MYSQL_SOCKET:-/workspace/.devcontainer/.mysql.sock}" +PORT="${MYSQL_PORT:-3306}" +PIDFILE="${MYSQL_PIDFILE:-/workspace/.devcontainer/.mysql.pid}" +LOGFILE="${MYSQL_LOGFILE:-/workspace/.devcontainer/.mysql.log}" + +if ! command -v "$MYSQLD" >/dev/null 2>&1; then + echo "mysqld not found at $MYSQLD; skipping mysql start" + exit 0 +fi + +mkdir -p "$(dirname "$SOCKET")" "$DATADIR" "$(dirname "$PIDFILE")" "$(dirname "$LOGFILE")" + +# Initialize data directory if empty (insecure root, no password) +if [ -z "$(ls -A "$DATADIR" 2>/dev/null || true)" ]; then + "$MYSQLD" --initialize-insecure --datadir="$DATADIR" --user="$(id -un)" >/dev/null 2>&1 || true +fi + +# Already up? +if "$MYSQLADMIN" --socket="$SOCKET" --user=root ping >/dev/null 2>&1; then + exit 0 +fi + +# Start daemonized bound to 127.0.0.1 +nohup "$MYSQLD" \ + --datadir="$DATADIR" \ + --socket="$SOCKET" \ + --port="$PORT" \ + --bind-address=127.0.0.1 \ + --pid-file="$PIDFILE" \ + --log-error="$LOGFILE" \ + --user="$(id -un)" \ + --daemonize >/dev/null 2>&1 || true + +# Wait up to 60s for readiness +for i in {1..60}; do + if "$MYSQLADMIN" --socket="$SOCKET" --user=root ping >/dev/null 2>&1; then + exit 0 + fi + sleep 1 +fi + +echo "mysqld failed to start; see $LOGFILE" +exit 0 + + From 042a0c205399c8f163fb0d4489c88ea18da31329 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 19 Sep 2025 14:51:41 +0000 Subject: [PATCH 06/39] updates and perms --- .devcontainer/start-mysql.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .devcontainer/start-mysql.sh diff --git a/.devcontainer/start-mysql.sh b/.devcontainer/start-mysql.sh old mode 100644 new mode 100755 From 17c8546cf2d45f3389e33834310692d31b6b7095 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 19 Sep 2025 15:09:19 +0000 Subject: [PATCH 07/39] restore changes --- .devcontainer/init-mysql.sh | 20 +++++++++++++++++--- .devcontainer/init-postgres.sh | 8 ++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.devcontainer/init-mysql.sh b/.devcontainer/init-mysql.sh index 75631f75..10b0465f 100755 --- a/.devcontainer/init-mysql.sh +++ b/.devcontainer/init-mysql.sh @@ -6,6 +6,15 @@ if ! command -v mysql >/dev/null 2>&1; then exit 0 fi +# Use same socket as mysqld starter +SOCKET="${MYSQL_SOCKET:-/tmp/singularity-mysql.sock}" + +# One-time init guard +MARKER="/workspace/.devcontainer/.mysql-initialized" +if [ -f "$MARKER" ]; then + exit 0 +fi + # Determine root auth flags MYSQL_ROOT_FLAGS=("-uroot") if [ -n "${MYSQL_ROOT_PASSWORD:-}" ]; then @@ -14,14 +23,14 @@ fi # Wait for server readiness (best effort) for i in {1..60}; do - if mysqladmin ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then + if mysqladmin --socket="$SOCKET" ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then break fi sleep 1 done # Bail if still unreachable -if ! mysqladmin ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then +if ! mysqladmin --socket="$SOCKET" ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then exit 0 fi @@ -30,11 +39,16 @@ DB=${MYSQL_DATABASE:-singularity} USER=${MYSQL_USER:-singularity} PASS=${MYSQL_PASSWORD:-singularity} -mysql "${MYSQL_ROOT_FLAGS[@]}" </dev/null 2>&1; then exit 0 fi +# One-time init guard +MARKER="/workspace/.devcontainer/.pg-initialized" +if [ -f "$MARKER" ]; then + exit 0 +fi + # Wait for server readiness (best effort) for i in {1..60}; do if pg_isready -q; then @@ -27,4 +33,6 @@ if ! PGPASSWORD="" psql --no-password -U postgres -d postgres -tAc "SELECT 1 FRO PGPASSWORD="" createdb --no-password -U postgres singularity fi +# mark initialized +touch "$MARKER" From 4440bac393acda10a2ead9fcf67d3fb841090934 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 19 Sep 2025 15:13:21 +0000 Subject: [PATCH 08/39] more restore --- .devcontainer/start-mysql.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.devcontainer/start-mysql.sh b/.devcontainer/start-mysql.sh index fe5faf46..28ee3dee 100755 --- a/.devcontainer/start-mysql.sh +++ b/.devcontainer/start-mysql.sh @@ -5,12 +5,12 @@ set -euo pipefail MYSQLD="${MYSQLD:-/home/linuxbrew/.linuxbrew/opt/mysql/bin/mysqld}" MYSQLADMIN="${MYSQLADMIN:-/home/linuxbrew/.linuxbrew/bin/mysqladmin}" -# Runtime locations inside workspace (owned by repo user) -DATADIR="${MYSQL_DATADIR:-/workspace/.devcontainer/.mysql-data}" -SOCKET="${MYSQL_SOCKET:-/workspace/.devcontainer/.mysql.sock}" +# Runtime locations under /tmp so tests are ephemeral and permissions are simple +DATADIR="${MYSQL_DATADIR:-/tmp/singularity-mysql-data}" +SOCKET="${MYSQL_SOCKET:-/tmp/singularity-mysql.sock}" PORT="${MYSQL_PORT:-3306}" -PIDFILE="${MYSQL_PIDFILE:-/workspace/.devcontainer/.mysql.pid}" -LOGFILE="${MYSQL_LOGFILE:-/workspace/.devcontainer/.mysql.log}" +PIDFILE="${MYSQL_PIDFILE:-/tmp/singularity-mysql.pid}" +LOGFILE="${MYSQL_LOGFILE:-/tmp/singularity-mysql.log}" if ! command -v "$MYSQLD" >/dev/null 2>&1; then echo "mysqld not found at $MYSQLD; skipping mysql start" @@ -46,7 +46,7 @@ for i in {1..60}; do exit 0 fi sleep 1 -fi +done echo "mysqld failed to start; see $LOGFILE" exit 0 From 504fd45a380465587dc65a5d0347f961ba8deb56 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 19 Sep 2025 15:20:56 +0000 Subject: [PATCH 09/39] fix passwords --- .devcontainer/init-postgres.sh | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.devcontainer/init-postgres.sh b/.devcontainer/init-postgres.sh index 6e7af517..f5e782af 100755 --- a/.devcontainer/init-postgres.sh +++ b/.devcontainer/init-postgres.sh @@ -6,12 +6,6 @@ if ! command -v pg_isready >/dev/null 2>&1; then exit 0 fi -# One-time init guard -MARKER="/workspace/.devcontainer/.pg-initialized" -if [ -f "$MARKER" ]; then - exit 0 -fi - # Wait for server readiness (best effort) for i in {1..60}; do if pg_isready -q; then @@ -25,14 +19,18 @@ if ! PGPASSWORD="" psql --no-password -U postgres -d postgres -tc "SELECT 1" >/d exit 0 fi -# Create role if missing (idempotent) -PGPASSWORD="" psql --no-password -U postgres -d postgres -v ON_ERROR_STOP=1 -c "DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'singularity') THEN CREATE ROLE singularity WITH LOGIN SUPERUSER PASSWORD 'singularity'; END IF; END $$;" +# Ensure role exists and password is set (idempotent, always reset password) +PGPASSWORD="" psql --no-password -U postgres -d postgres -v ON_ERROR_STOP=1 -c "DO $$ +BEGIN + IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'singularity') THEN + ALTER ROLE singularity WITH LOGIN SUPERUSER PASSWORD 'singularity'; + ELSE + CREATE ROLE singularity WITH LOGIN SUPERUSER PASSWORD 'singularity'; + END IF; +END $$;" # Create database if missing (idempotent) if ! PGPASSWORD="" psql --no-password -U postgres -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = 'singularity'" | grep -q 1; then PGPASSWORD="" createdb --no-password -U postgres singularity fi -# mark initialized -touch "$MARKER" - From e1e5514dab64b45bfca4bddf33b6a09ab90ec00b Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 19 Sep 2025 17:02:38 +0000 Subject: [PATCH 10/39] hopefully fix DB craziness --- .devcontainer/devcontainer.json | 2 +- .devcontainer/init-postgres.sh | 36 ----------------------- .devcontainer/start-mysql.sh | 51 +++++++++------------------------ 3 files changed, 15 insertions(+), 74 deletions(-) delete mode 100755 .devcontainer/init-postgres.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index dc423416..54706971 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -26,7 +26,7 @@ }, "forwardPorts": [], "postCreateCommand": "go mod download", - "postStartCommand": "/bin/bash -lc '/workspace/.devcontainer/init-postgres.sh && /workspace/.devcontainer/init-mysql.sh'", + "postStartCommand": "/bin/bash -lc '/usr/local/share/pq-init.sh && sudo service postgresql restart && /workspace/.devcontainer/start-mysql.sh && /workspace/.devcontainer/init-mysql.sh'", "remoteUser": "vscode", "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached,relabel=private", "workspaceFolder": "/workspace", diff --git a/.devcontainer/init-postgres.sh b/.devcontainer/init-postgres.sh deleted file mode 100755 index f5e782af..00000000 --- a/.devcontainer/init-postgres.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# If postgres isn't present in this image, exit quietly -if ! command -v pg_isready >/dev/null 2>&1; then - exit 0 -fi - -# Wait for server readiness (best effort) -for i in {1..60}; do - if pg_isready -q; then - break - fi - sleep 1 -done - -# If we still can't connect, bail (container may not include a running server) -if ! PGPASSWORD="" psql --no-password -U postgres -d postgres -tc "SELECT 1" >/dev/null 2>&1; then - exit 0 -fi - -# Ensure role exists and password is set (idempotent, always reset password) -PGPASSWORD="" psql --no-password -U postgres -d postgres -v ON_ERROR_STOP=1 -c "DO $$ -BEGIN - IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'singularity') THEN - ALTER ROLE singularity WITH LOGIN SUPERUSER PASSWORD 'singularity'; - ELSE - CREATE ROLE singularity WITH LOGIN SUPERUSER PASSWORD 'singularity'; - END IF; -END $$;" - -# Create database if missing (idempotent) -if ! PGPASSWORD="" psql --no-password -U postgres -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = 'singularity'" | grep -q 1; then - PGPASSWORD="" createdb --no-password -U postgres singularity -fi - diff --git a/.devcontainer/start-mysql.sh b/.devcontainer/start-mysql.sh index 28ee3dee..b14dce16 100755 --- a/.devcontainer/start-mysql.sh +++ b/.devcontainer/start-mysql.sh @@ -1,54 +1,31 @@ #!/usr/bin/env bash set -euo pipefail -# Paths (homebrew mysql in devcontainer) -MYSQLD="${MYSQLD:-/home/linuxbrew/.linuxbrew/opt/mysql/bin/mysqld}" -MYSQLADMIN="${MYSQLADMIN:-/home/linuxbrew/.linuxbrew/bin/mysqladmin}" +# Start MySQL using homebrew's mysql.server command +# This is provided by the ghcr.io/devcontainers-extra/features/mysql-homebrew feature -# Runtime locations under /tmp so tests are ephemeral and permissions are simple -DATADIR="${MYSQL_DATADIR:-/tmp/singularity-mysql-data}" -SOCKET="${MYSQL_SOCKET:-/tmp/singularity-mysql.sock}" -PORT="${MYSQL_PORT:-3306}" -PIDFILE="${MYSQL_PIDFILE:-/tmp/singularity-mysql.pid}" -LOGFILE="${MYSQL_LOGFILE:-/tmp/singularity-mysql.log}" - -if ! command -v "$MYSQLD" >/dev/null 2>&1; then - echo "mysqld not found at $MYSQLD; skipping mysql start" +# Check if already running +if mysql.server status >/dev/null 2>&1; then + echo "MySQL already running" exit 0 fi -mkdir -p "$(dirname "$SOCKET")" "$DATADIR" "$(dirname "$PIDFILE")" "$(dirname "$LOGFILE")" - -# Initialize data directory if empty (insecure root, no password) -if [ -z "$(ls -A "$DATADIR" 2>/dev/null || true)" ]; then - "$MYSQLD" --initialize-insecure --datadir="$DATADIR" --user="$(id -un)" >/dev/null 2>&1 || true -fi +echo "Starting MySQL server..." +mysql.server start -# Already up? -if "$MYSQLADMIN" --socket="$SOCKET" --user=root ping >/dev/null 2>&1; then - exit 0 -fi +# The MySQL socket location for tests +SOCKET="${MYSQL_SOCKET:-/tmp/singularity-mysql.sock}" -# Start daemonized bound to 127.0.0.1 -nohup "$MYSQLD" \ - --datadir="$DATADIR" \ - --socket="$SOCKET" \ - --port="$PORT" \ - --bind-address=127.0.0.1 \ - --pid-file="$PIDFILE" \ - --log-error="$LOGFILE" \ - --user="$(id -un)" \ - --daemonize >/dev/null 2>&1 || true - -# Wait up to 60s for readiness +# Wait for MySQL to be ready for i in {1..60}; do - if "$MYSQLADMIN" --socket="$SOCKET" --user=root ping >/dev/null 2>&1; then + if mysqladmin --socket="$SOCKET" --user=root ping >/dev/null 2>&1; then + echo "MySQL server is ready" exit 0 fi sleep 1 done -echo "mysqld failed to start; see $LOGFILE" -exit 0 +echo "MySQL server failed to start" +exit 1 From b17019c628d6170f24ef752c0e3e1429396cac82 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Sat, 20 Sep 2025 14:12:51 +0000 Subject: [PATCH 11/39] finally actually fix the DB --- .devcontainer/devcontainer.json | 5 +++-- .devcontainer/init-mysql.sh | 4 ++-- .devcontainer/start-mysql.sh | 8 +++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 54706971..64b5b784 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -26,7 +26,7 @@ }, "forwardPorts": [], "postCreateCommand": "go mod download", - "postStartCommand": "/bin/bash -lc '/usr/local/share/pq-init.sh && sudo service postgresql restart && /workspace/.devcontainer/start-mysql.sh && /workspace/.devcontainer/init-mysql.sh'", + "postStartCommand": "/bin/bash -lc 'echo \"local all all trust\nhost all all 127.0.0.1/32 trust\nhost all all ::1/128 trust\" | sudo tee /etc/postgresql/16/main/pg_hba.conf > /dev/null && sudo service postgresql restart && /workspace/.devcontainer/start-mysql.sh && /workspace/.devcontainer/init-mysql.sh'", "remoteUser": "vscode", "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached,relabel=private", "workspaceFolder": "/workspace", @@ -34,7 +34,8 @@ "GOPATH": "/home/vscode/go", "MYSQL_DATABASE": "singularity", "MYSQL_USER": "singularity", - "MYSQL_PASSWORD": "singularity" + "MYSQL_PASSWORD": "singularity", + "MYSQL_SOCKET": "/tmp/mysql.sock" }, "runArgs": ["--userns=keep-id"], "containerUser": "vscode" diff --git a/.devcontainer/init-mysql.sh b/.devcontainer/init-mysql.sh index 10b0465f..0f0a7265 100755 --- a/.devcontainer/init-mysql.sh +++ b/.devcontainer/init-mysql.sh @@ -6,8 +6,8 @@ if ! command -v mysql >/dev/null 2>&1; then exit 0 fi -# Use same socket as mysqld starter -SOCKET="${MYSQL_SOCKET:-/tmp/singularity-mysql.sock}" +# Use same socket as mysql.server (homebrew default) +SOCKET="${MYSQL_SOCKET:-/tmp/mysql.sock}" # One-time init guard MARKER="/workspace/.devcontainer/.mysql-initialized" diff --git a/.devcontainer/start-mysql.sh b/.devcontainer/start-mysql.sh index b14dce16..cf6092f9 100755 --- a/.devcontainer/start-mysql.sh +++ b/.devcontainer/start-mysql.sh @@ -13,8 +13,8 @@ fi echo "Starting MySQL server..." mysql.server start -# The MySQL socket location for tests -SOCKET="${MYSQL_SOCKET:-/tmp/singularity-mysql.sock}" +# MySQL uses /tmp/mysql.sock by default when started with mysql.server +SOCKET="/tmp/mysql.sock" # Wait for MySQL to be ready for i in {1..60}; do @@ -26,6 +26,4 @@ for i in {1..60}; do done echo "MySQL server failed to start" -exit 1 - - +exit 1 \ No newline at end of file From 7c7d28237dc7a558ebf7f93cc239a19d30fd7400 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Mon, 22 Sep 2025 17:41:51 +0000 Subject: [PATCH 12/39] devcontainer based tests --- .github/workflows/test-devcontainer.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/test-devcontainer.yaml diff --git a/.github/workflows/test-devcontainer.yaml b/.github/workflows/test-devcontainer.yaml new file mode 100644 index 00000000..2ac5ef7f --- /dev/null +++ b/.github/workflows/test-devcontainer.yaml @@ -0,0 +1,18 @@ +name: Test with Devcontainer +on: + push: + branches: [ "local/devcontainer" ] + pull_request: + branches: [ "main" ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Run tests in devcontainer + uses: devcontainers/ci@v0.3 + with: + runCmd: make test \ No newline at end of file From 45815df7de3ee8689ba8e395c54f2b089465289d Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Wed, 24 Sep 2025 17:39:00 +0200 Subject: [PATCH 13/39] workaround for https://github.com/devcontainers/ci/issues/375 --- .devcontainer/devcontainer.json | 2 +- .devcontainer/post-create.sh | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100755 .devcontainer/post-create.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 64b5b784..a4e2f9ad 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -25,7 +25,7 @@ "ghcr.io/devcontainers-extra/features/mysql-homebrew:1": {} }, "forwardPorts": [], - "postCreateCommand": "go mod download", + "postCreateCommand": "/bin/bash -lc '/workspace/.devcontainer/post-create.sh'", "postStartCommand": "/bin/bash -lc 'echo \"local all all trust\nhost all all 127.0.0.1/32 trust\nhost all all ::1/128 trust\" | sudo tee /etc/postgresql/16/main/pg_hba.conf > /dev/null && sudo service postgresql restart && /workspace/.devcontainer/start-mysql.sh && /workspace/.devcontainer/init-mysql.sh'", "remoteUser": "vscode", "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached,relabel=private", diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100755 index 00000000..7b92e32d --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Initialize Go modules +go mod download + + From 8091652dc26d9d133f9dc9703518febcde186ddf Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Wed, 24 Sep 2025 17:58:40 +0200 Subject: [PATCH 14/39] try a more universal relabel? --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a4e2f9ad..c73e6061 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -28,7 +28,7 @@ "postCreateCommand": "/bin/bash -lc '/workspace/.devcontainer/post-create.sh'", "postStartCommand": "/bin/bash -lc 'echo \"local all all trust\nhost all all 127.0.0.1/32 trust\nhost all all ::1/128 trust\" | sudo tee /etc/postgresql/16/main/pg_hba.conf > /dev/null && sudo service postgresql restart && /workspace/.devcontainer/start-mysql.sh && /workspace/.devcontainer/init-mysql.sh'", "remoteUser": "vscode", - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached,relabel=private", + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace:Z,type=bind,consistency=cached", "workspaceFolder": "/workspace", "containerEnv": { "GOPATH": "/home/vscode/go", From f8ac1aca55fc69ef9e039a05f4da0bc9683cf1f4 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Wed, 24 Sep 2025 18:35:03 +0200 Subject: [PATCH 15/39] simplify and generalize --- .devcontainer/devcontainer.json | 6 ++---- .devcontainer/init-mysql.sh | 9 ++------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c73e6061..4f48c75f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -25,11 +25,9 @@ "ghcr.io/devcontainers-extra/features/mysql-homebrew:1": {} }, "forwardPorts": [], - "postCreateCommand": "/bin/bash -lc '/workspace/.devcontainer/post-create.sh'", - "postStartCommand": "/bin/bash -lc 'echo \"local all all trust\nhost all all 127.0.0.1/32 trust\nhost all all ::1/128 trust\" | sudo tee /etc/postgresql/16/main/pg_hba.conf > /dev/null && sudo service postgresql restart && /workspace/.devcontainer/start-mysql.sh && /workspace/.devcontainer/init-mysql.sh'", + "postCreateCommand": "/bin/bash -lc '${containerWorkspaceFolder}/.devcontainer/post-create.sh'", + "postStartCommand": "/bin/bash -lc 'echo \"local all all trust\nhost all all 127.0.0.1/32 trust\nhost all all ::1/128 trust\" | sudo tee /etc/postgresql/16/main/pg_hba.conf > /dev/null && sudo service postgresql restart && ${containerWorkspaceFolder}/.devcontainer/start-mysql.sh && ${containerWorkspaceFolder}/.devcontainer/init-mysql.sh'", "remoteUser": "vscode", - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace:Z,type=bind,consistency=cached", - "workspaceFolder": "/workspace", "containerEnv": { "GOPATH": "/home/vscode/go", "MYSQL_DATABASE": "singularity", diff --git a/.devcontainer/init-mysql.sh b/.devcontainer/init-mysql.sh index 0f0a7265..91273c62 100755 --- a/.devcontainer/init-mysql.sh +++ b/.devcontainer/init-mysql.sh @@ -9,11 +9,7 @@ fi # Use same socket as mysql.server (homebrew default) SOCKET="${MYSQL_SOCKET:-/tmp/mysql.sock}" -# One-time init guard -MARKER="/workspace/.devcontainer/.mysql-initialized" -if [ -f "$MARKER" ]; then - exit 0 -fi +## Removed one-time init guard; operations below are idempotent # Determine root auth flags MYSQL_ROOT_FLAGS=("-uroot") @@ -48,7 +44,6 @@ GRANT ALL PRIVILEGES ON \`${DB}\`.* TO '${USER}'@'%'; FLUSH PRIVILEGES; SQL -# mark initialized -touch "$MARKER" +## No marker file; script can run safely on every start From 4b93bee46a616be8c3285397f1c976c9cecf60d7 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Wed, 24 Sep 2025 19:26:41 +0200 Subject: [PATCH 16/39] move podman specific stuff out entirely --- .devcontainer/devcontainer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4f48c75f..e508a9ac 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -35,7 +35,6 @@ "MYSQL_PASSWORD": "singularity", "MYSQL_SOCKET": "/tmp/mysql.sock" }, - "runArgs": ["--userns=keep-id"], "containerUser": "vscode" } From 4eff08647db7006e95b0efefd9be4da92c029282 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Thu, 25 Sep 2025 13:22:53 +0000 Subject: [PATCH 17/39] try 1:1 podman run --- .devcontainer/devcontainer.json | 1 + .github/workflows/devcontainer-podman.yml | 39 +++++++++++++++++++++++ .github/workflows/test-devcontainer.yaml | 18 +++-------- 3 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/devcontainer-podman.yml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e508a9ac..4f48c75f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -35,6 +35,7 @@ "MYSQL_PASSWORD": "singularity", "MYSQL_SOCKET": "/tmp/mysql.sock" }, + "runArgs": ["--userns=keep-id"], "containerUser": "vscode" } diff --git a/.github/workflows/devcontainer-podman.yml b/.github/workflows/devcontainer-podman.yml new file mode 100644 index 00000000..1a7b9da7 --- /dev/null +++ b/.github/workflows/devcontainer-podman.yml @@ -0,0 +1,39 @@ +name: CI (Podman Devcontainer) + +on: + push: + branches: [ local/devcontainer ] + pull_request: + branches: [ local/devcontainer ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Show Podman version + run: podman --version + + - name: Start Podman Docker-compatible service + run: | + set -euo pipefail + podman info + nohup podman system service -t 0 tcp:127.0.0.1:8080 > podman-service.log 2>&1 & + echo "DOCKER_HOST=tcp://127.0.0.1:8080" >> $GITHUB_ENV + + - name: Install Dev Containers CLI + run: | + npm i -g @devcontainers/cli + devcontainer --version + + - name: Build devcontainer (Podman) + run: | + devcontainer up --workspace-folder . --remove-existing-container --id-label ci=podman + + - name: Run tests in devcontainer + run: | + devcontainer exec --workspace-folder . -- bash -lc 'go version && go test ./...' + + diff --git a/.github/workflows/test-devcontainer.yaml b/.github/workflows/test-devcontainer.yaml index 2ac5ef7f..867924f2 100644 --- a/.github/workflows/test-devcontainer.yaml +++ b/.github/workflows/test-devcontainer.yaml @@ -1,18 +1,8 @@ -name: Test with Devcontainer +name: disabled (replaced by Podman devcontainer workflow) on: - push: - branches: [ "local/devcontainer" ] - pull_request: - branches: [ "main" ] - + workflow_call: jobs: - test: + skip: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Run tests in devcontainer - uses: devcontainers/ci@v0.3 - with: - runCmd: make test \ No newline at end of file + - run: echo "This workflow is disabled. See devcontainer-podman.yml." \ No newline at end of file From ba37840a65d94de14cf24728c00448ed857ad4d6 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Thu, 25 Sep 2025 13:42:05 +0000 Subject: [PATCH 18/39] kill docker with fire --- .github/workflows/devcontainer-podman.yml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/devcontainer-podman.yml b/.github/workflows/devcontainer-podman.yml index 1a7b9da7..55a6a375 100644 --- a/.github/workflows/devcontainer-podman.yml +++ b/.github/workflows/devcontainer-podman.yml @@ -13,15 +13,25 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Show Podman version - run: podman --version - - - name: Start Podman Docker-compatible service + - name: Disable Docker engine and install podman-docker + run: | + set -euo pipefail + sudo systemctl stop docker.socket docker || true + sudo systemctl disable docker.socket docker || true + sudo systemctl mask docker.socket docker || true + sudo service docker stop || true + sudo apt-get update + sudo apt-get install -y podman-docker + docker --version + podman --version + + - name: Start Podman service socket (Docker-compatible) run: | set -euo pipefail podman info - nohup podman system service -t 0 tcp:127.0.0.1:8080 > podman-service.log 2>&1 & - echo "DOCKER_HOST=tcp://127.0.0.1:8080" >> $GITHUB_ENV + nohup podman system service -t 0 unix:///tmp/podman.sock > podman-service.log 2>&1 & + echo "DOCKER_HOST=unix:///tmp/podman.sock" >> $GITHUB_ENV + echo "DOCKER_CLI_HINTS=false" >> $GITHUB_ENV - name: Install Dev Containers CLI run: | From cb509c87b281a6f8d349aa3f2f25a7de6d59529d Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 26 Sep 2025 14:32:57 +0000 Subject: [PATCH 19/39] use my podman-docker action --- .github/workflows/devcontainer-podman.yml | 47 +++++++---------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/.github/workflows/devcontainer-podman.yml b/.github/workflows/devcontainer-podman.yml index 55a6a375..18ba3c14 100644 --- a/.github/workflows/devcontainer-podman.yml +++ b/.github/workflows/devcontainer-podman.yml @@ -13,37 +13,16 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Disable Docker engine and install podman-docker - run: | - set -euo pipefail - sudo systemctl stop docker.socket docker || true - sudo systemctl disable docker.socket docker || true - sudo systemctl mask docker.socket docker || true - sudo service docker stop || true - sudo apt-get update - sudo apt-get install -y podman-docker - docker --version - podman --version - - - name: Start Podman service socket (Docker-compatible) - run: | - set -euo pipefail - podman info - nohup podman system service -t 0 unix:///tmp/podman.sock > podman-service.log 2>&1 & - echo "DOCKER_HOST=unix:///tmp/podman.sock" >> $GITHUB_ENV - echo "DOCKER_CLI_HINTS=false" >> $GITHUB_ENV - - - name: Install Dev Containers CLI - run: | - npm i -g @devcontainers/cli - devcontainer --version - - - name: Build devcontainer (Podman) - run: | - devcontainer up --workspace-folder . --remove-existing-container --id-label ci=podman - - - name: Run tests in devcontainer - run: | - devcontainer exec --workspace-folder . -- bash -lc 'go version && go test ./...' - - + - name: Setup Podman as Docker + uses: parkan/github-actions/setup-podman-docker@v1 + with: + disable-docker: true + cache-storage: false # Disabled until cache issues resolved + + - name: Run Devcontainer Tests + uses: parkan/github-actions/devcontainer-test@v1 + with: + workspace-folder: . + container-runtime: podman + container-id-label: ci=podman + test-command: 'go version && go test ./...' \ No newline at end of file From 269fffb48730a72612c7fe5e8ac9456cfdb044c4 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 26 Sep 2025 15:59:18 +0000 Subject: [PATCH 20/39] drop linuxbrewed mysql, user scope psql --- .github/workflows/devcontainer-podman.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/devcontainer-podman.yml b/.github/workflows/devcontainer-podman.yml index 18ba3c14..f3be237b 100644 --- a/.github/workflows/devcontainer-podman.yml +++ b/.github/workflows/devcontainer-podman.yml @@ -25,4 +25,4 @@ jobs: workspace-folder: . container-runtime: podman container-id-label: ci=podman - test-command: 'go version && go test ./...' \ No newline at end of file + test-command: 'cd·/workspaces/singularity/ && make test' \ No newline at end of file From 97979cb1aa53fa8c846d34e2a0c86bd408c7d849 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 26 Sep 2025 16:07:04 +0000 Subject: [PATCH 21/39] missing files --- .devcontainer/devcontainer.json | 8 ++++---- .devcontainer/post-create.sh | 8 ++++++++ .devcontainer/start-mysql.sh | 13 ++++++------- .devcontainer/start-postgres.sh | 23 +++++++++++++++++++++++ 4 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 .devcontainer/start-postgres.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4f48c75f..3e142136 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -21,19 +21,19 @@ }, "ghcr.io/itsmechlark/features/postgresql:1": { "version": "16" - }, - "ghcr.io/devcontainers-extra/features/mysql-homebrew:1": {} + } }, "forwardPorts": [], "postCreateCommand": "/bin/bash -lc '${containerWorkspaceFolder}/.devcontainer/post-create.sh'", - "postStartCommand": "/bin/bash -lc 'echo \"local all all trust\nhost all all 127.0.0.1/32 trust\nhost all all ::1/128 trust\" | sudo tee /etc/postgresql/16/main/pg_hba.conf > /dev/null && sudo service postgresql restart && ${containerWorkspaceFolder}/.devcontainer/start-mysql.sh && ${containerWorkspaceFolder}/.devcontainer/init-mysql.sh'", + "postStartCommand": "/bin/bash -lc '${containerWorkspaceFolder}/.devcontainer/start-postgres.sh && ${containerWorkspaceFolder}/.devcontainer/start-mysql.sh && ${containerWorkspaceFolder}/.devcontainer/init-mysql.sh'", "remoteUser": "vscode", "containerEnv": { "GOPATH": "/home/vscode/go", "MYSQL_DATABASE": "singularity", "MYSQL_USER": "singularity", "MYSQL_PASSWORD": "singularity", - "MYSQL_SOCKET": "/tmp/mysql.sock" + "MYSQL_SOCKET": "/var/run/mysqld/mysqld.sock", + "PGDATA": "${containerWorkspaceFolder}/.devcontainer/pgdata" }, "runArgs": ["--userns=keep-id"], "containerUser": "vscode" diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 7b92e32d..fd240f5a 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -4,4 +4,12 @@ set -euo pipefail # Initialize Go modules go mod download +if ! command -v mysqld >/dev/null 2>&1; then + sudo apt-get update + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server mariadb-client >/dev/null + sudo mkdir -p /var/run/mysqld + sudo chown -R mysql:mysql /var/run/mysqld || true + sudo chmod 775 /var/run/mysqld || true +fi + diff --git a/.devcontainer/start-mysql.sh b/.devcontainer/start-mysql.sh index cf6092f9..83880672 100755 --- a/.devcontainer/start-mysql.sh +++ b/.devcontainer/start-mysql.sh @@ -1,20 +1,19 @@ #!/usr/bin/env bash set -euo pipefail -# Start MySQL using homebrew's mysql.server command -# This is provided by the ghcr.io/devcontainers-extra/features/mysql-homebrew feature +# Start MariaDB/MySQL via system service -# Check if already running -if mysql.server status >/dev/null 2>&1; then +# If already running, exit +if pgrep -x mysqld >/dev/null 2>&1; then echo "MySQL already running" exit 0 fi echo "Starting MySQL server..." -mysql.server start +sudo service mysql start >/dev/null 2>&1 || sudo service mariadb start >/dev/null 2>&1 || true -# MySQL uses /tmp/mysql.sock by default when started with mysql.server -SOCKET="/tmp/mysql.sock" +# Debian socket path +SOCKET="/var/run/mysqld/mysqld.sock" # Wait for MySQL to be ready for i in {1..60}; do diff --git a/.devcontainer/start-postgres.sh b/.devcontainer/start-postgres.sh new file mode 100644 index 00000000..649492b8 --- /dev/null +++ b/.devcontainer/start-postgres.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail + +PGDATA_DIR="${PGDATA:-${PWD}/.devcontainer/pgdata}" +LOG_FILE="${PGDATA_DIR}/postgres.log" + +sudo mkdir -p "$PGDATA_DIR" +sudo chown -R postgres:postgres "$PGDATA_DIR" + +if [ ! -f "$PGDATA_DIR/PG_VERSION" ]; then + sudo -u postgres /usr/lib/postgresql/16/bin/initdb -D "$PGDATA_DIR" --auth trust --auth-local trust --auth-host trust + sudo -u postgres bash -lc "echo \"listen_addresses='*'\" >> '$PGDATA_DIR/postgresql.conf'" + sudo -u postgres bash -lc "{ + echo 'host all all 0.0.0.0/0 trust' + echo 'host all all ::/0 trust' + echo 'host all all ::1/128 trust' + echo 'local all all trust' + } >> '$PGDATA_DIR/pg_hba.conf'" +fi + +sudo -u postgres /usr/lib/postgresql/16/bin/pg_ctl -D "$PGDATA_DIR" -l "$LOG_FILE" -w start + + From 2bf7a3ceae61820bfaec3c34ea3076a2d2319ba0 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 26 Sep 2025 16:26:03 +0000 Subject: [PATCH 22/39] perms --- .devcontainer/post-create.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index fd240f5a..c3a9b8ff 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -4,6 +4,12 @@ set -euo pipefail # Initialize Go modules go mod download +chmod +x .devcontainer/*.sh || true + +# Prepare user-owned Postgres data directory +sudo mkdir -p .devcontainer/pgdata +sudo chown -R postgres:postgres .devcontainer/pgdata || true + if ! command -v mysqld >/dev/null 2>&1; then sudo apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server mariadb-client >/dev/null From 649a873f270f2aa237f0e107785ba7857b04c841 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 26 Sep 2025 16:36:27 +0000 Subject: [PATCH 23/39] noninteractive sudo --- .devcontainer/start-postgres.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.devcontainer/start-postgres.sh b/.devcontainer/start-postgres.sh index 649492b8..808c8f14 100644 --- a/.devcontainer/start-postgres.sh +++ b/.devcontainer/start-postgres.sh @@ -4,13 +4,13 @@ set -euo pipefail PGDATA_DIR="${PGDATA:-${PWD}/.devcontainer/pgdata}" LOG_FILE="${PGDATA_DIR}/postgres.log" -sudo mkdir -p "$PGDATA_DIR" -sudo chown -R postgres:postgres "$PGDATA_DIR" +sudo -n mkdir -p "$PGDATA_DIR" +sudo -n chown -R postgres:postgres "$PGDATA_DIR" if [ ! -f "$PGDATA_DIR/PG_VERSION" ]; then - sudo -u postgres /usr/lib/postgresql/16/bin/initdb -D "$PGDATA_DIR" --auth trust --auth-local trust --auth-host trust - sudo -u postgres bash -lc "echo \"listen_addresses='*'\" >> '$PGDATA_DIR/postgresql.conf'" - sudo -u postgres bash -lc "{ + sudo -n -u postgres /usr/lib/postgresql/16/bin/initdb -D "$PGDATA_DIR" --auth trust --auth-local trust --auth-host trust + sudo -n -u postgres bash -lc "echo \"listen_addresses='*'\" >> '$PGDATA_DIR/postgresql.conf'" + sudo -n -u postgres bash -lc "{ echo 'host all all 0.0.0.0/0 trust' echo 'host all all ::/0 trust' echo 'host all all ::1/128 trust' @@ -18,6 +18,6 @@ if [ ! -f "$PGDATA_DIR/PG_VERSION" ]; then } >> '$PGDATA_DIR/pg_hba.conf'" fi -sudo -u postgres /usr/lib/postgresql/16/bin/pg_ctl -D "$PGDATA_DIR" -l "$LOG_FILE" -w start +sudo -n -u postgres /usr/lib/postgresql/16/bin/pg_ctl -D "$PGDATA_DIR" -l "$LOG_FILE" -w start From 7375d6dc6b8de4a400926fe7e74c2a8da7ce770f Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Thu, 2 Oct 2025 14:02:02 +0000 Subject: [PATCH 24/39] meticulously re-engineer the devcontainer --- .devcontainer/Dockerfile | 36 ++++++++++++++++++++++ .devcontainer/devcontainer.json | 26 +++++++++------- .devcontainer/init-mysql.sh | 4 +-- .devcontainer/post-create.sh | 12 -------- .devcontainer/start-mysql.sh | 53 +++++++++++++++++++++++++++------ .devcontainer/start-postgres.sh | 21 ++++++------- 6 files changed, 108 insertions(+), 44 deletions(-) create mode 100644 .devcontainer/Dockerfile mode change 100644 => 100755 .devcontainer/start-postgres.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..2fccf82f --- /dev/null +++ b/.devcontainer/Dockerfile @@ -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 + diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3e142136..f0e2ff23 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,14 @@ { "name": "singularity", - "image": "mcr.microsoft.com/devcontainers/go:1.24", + "build": { + "dockerfile": "Dockerfile", + "args": { + "GO_VERSION": "1.24", + "DEBIAN_CODENAME": "trixie", + "PG_MAJOR": "16", + "MARIADB_MAJOR": "12.0.2" + } + }, "customizations": { "vscode": { "extensions": [ @@ -15,15 +23,9 @@ } } }, - "features": { - "ghcr.io/devcontainers/features/go:1": { - "version": "1.24" - }, - "ghcr.io/itsmechlark/features/postgresql:1": { - "version": "16" - } - }, "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 && ${containerWorkspaceFolder}/.devcontainer/init-mysql.sh'", "remoteUser": "vscode", @@ -32,8 +34,10 @@ "MYSQL_DATABASE": "singularity", "MYSQL_USER": "singularity", "MYSQL_PASSWORD": "singularity", - "MYSQL_SOCKET": "/var/run/mysqld/mysqld.sock", - "PGDATA": "${containerWorkspaceFolder}/.devcontainer/pgdata" + "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" diff --git a/.devcontainer/init-mysql.sh b/.devcontainer/init-mysql.sh index 91273c62..94da58ca 100755 --- a/.devcontainer/init-mysql.sh +++ b/.devcontainer/init-mysql.sh @@ -6,8 +6,8 @@ if ! command -v mysql >/dev/null 2>&1; then exit 0 fi -# Use same socket as mysql.server (homebrew default) -SOCKET="${MYSQL_SOCKET:-/tmp/mysql.sock}" +# 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 diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index c3a9b8ff..2ac5dda3 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -6,16 +6,4 @@ go mod download chmod +x .devcontainer/*.sh || true -# Prepare user-owned Postgres data directory -sudo mkdir -p .devcontainer/pgdata -sudo chown -R postgres:postgres .devcontainer/pgdata || true - -if ! command -v mysqld >/dev/null 2>&1; then - sudo apt-get update - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server mariadb-client >/dev/null - sudo mkdir -p /var/run/mysqld - sudo chown -R mysql:mysql /var/run/mysqld || true - sudo chmod 775 /var/run/mysqld || true -fi - diff --git a/.devcontainer/start-mysql.sh b/.devcontainer/start-mysql.sh index 83880672..673f2d27 100755 --- a/.devcontainer/start-mysql.sh +++ b/.devcontainer/start-mysql.sh @@ -1,23 +1,53 @@ #!/usr/bin/env bash set -euo pipefail -# Start MariaDB/MySQL via system service +MYSQLD_BIN="$(command -v mariadbd || true)" +if [ -z "$MYSQLD_BIN" ]; then + MYSQLD_BIN="$(command -v mysqld || true)" +fi +if [ -z "$MYSQLD_BIN" ]; then + echo "Could not find MariaDB server binary (mariadbd or mysqld)" + exit 1 +fi + +# Start MariaDB as an unprivileged user using a user-owned data directory + +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" + +mkdir -p "${DATA_DIR}" "${MYSQL_BASE}" + +# Initialize data dir if missing +if [ ! -d "${DATA_DIR}/mysql" ]; then + echo "Initializing MariaDB data directory" + mariadb-install-db --datadir="${DATA_DIR}" --auth-root-authentication-method=normal --skip-test-db >/dev/null +fi # If already running, exit -if pgrep -x mysqld >/dev/null 2>&1; then +if [ -S "${SOCKET}" ] && mysqladmin --socket="${SOCKET}" ping >/dev/null 2>&1; then echo "MySQL already running" exit 0 fi -echo "Starting MySQL server..." -sudo service mysql start >/dev/null 2>&1 || sudo service mariadb start >/dev/null 2>&1 || true +echo "Starting MySQL server" +touch "${LOG_FILE}" +nohup "$MYSQLD_BIN" \ + --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 & -# Debian socket path -SOCKET="/var/run/mysqld/mysqld.sock" - -# Wait for MySQL to be ready +# Wait for MySQL to be ready (log-based + socket existence) for i in {1..60}; do - if mysqladmin --socket="$SOCKET" --user=root ping >/dev/null 2>&1; then + if [ -S "${SOCKET}" ] && grep -q "ready for connections" "${LOG_FILE}" >/dev/null 2>&1; then echo "MySQL server is ready" exit 0 fi @@ -25,4 +55,9 @@ for i in {1..60}; do 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 \ No newline at end of file diff --git a/.devcontainer/start-postgres.sh b/.devcontainer/start-postgres.sh old mode 100644 new mode 100755 index 808c8f14..af02d3e6 --- a/.devcontainer/start-postgres.sh +++ b/.devcontainer/start-postgres.sh @@ -1,23 +1,24 @@ #!/usr/bin/env bash set -euo pipefail -PGDATA_DIR="${PGDATA:-${PWD}/.devcontainer/pgdata}" +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}" -sudo -n mkdir -p "$PGDATA_DIR" -sudo -n chown -R postgres:postgres "$PGDATA_DIR" +mkdir -p "$PGDATA_DIR" "$PGSOCK_DIR" if [ ! -f "$PGDATA_DIR/PG_VERSION" ]; then - sudo -n -u postgres /usr/lib/postgresql/16/bin/initdb -D "$PGDATA_DIR" --auth trust --auth-local trust --auth-host trust - sudo -n -u postgres bash -lc "echo \"listen_addresses='*'\" >> '$PGDATA_DIR/postgresql.conf'" - sudo -n -u postgres bash -lc "{ - echo 'host all all 0.0.0.0/0 trust' - echo 'host all all ::/0 trust' + "${PG_BIN_DIR}/initdb" -D "$PGDATA_DIR" --auth trust --auth-local trust --auth-host trust + echo "listen_addresses='localhost'" >> "$PGDATA_DIR/postgresql.conf" + { + echo 'host all all 127.0.0.1/32 trust' echo 'host all all ::1/128 trust' echo 'local all all trust' - } >> '$PGDATA_DIR/pg_hba.conf'" + } >> "$PGDATA_DIR/pg_hba.conf" fi -sudo -n -u postgres /usr/lib/postgresql/16/bin/pg_ctl -D "$PGDATA_DIR" -l "$LOG_FILE" -w start +"${PG_BIN_DIR}/pg_ctl" -D "$PGDATA_DIR" -l "$LOG_FILE" -w -o "-p ${PGPORT} -k ${PGSOCK_DIR}" start From ea753e4c4fcc41b3a23503e72b726a2d79f026e3 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Thu, 2 Oct 2025 14:10:46 +0000 Subject: [PATCH 25/39] small workflow fix --- .github/workflows/devcontainer-podman.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/devcontainer-podman.yml b/.github/workflows/devcontainer-podman.yml index f3be237b..fd5a50db 100644 --- a/.github/workflows/devcontainer-podman.yml +++ b/.github/workflows/devcontainer-podman.yml @@ -25,4 +25,4 @@ jobs: workspace-folder: . container-runtime: podman container-id-label: ci=podman - test-command: 'cd·/workspaces/singularity/ && make test' \ No newline at end of file + test-command: 'make test' \ No newline at end of file From 4b02c14ea53fd1da570f416c7faecbe0bb42ef2d Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Thu, 2 Oct 2025 14:48:42 +0000 Subject: [PATCH 26/39] revert --- .github/workflows/devcontainer-podman.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/devcontainer-podman.yml b/.github/workflows/devcontainer-podman.yml index fd5a50db..3d80c1fd 100644 --- a/.github/workflows/devcontainer-podman.yml +++ b/.github/workflows/devcontainer-podman.yml @@ -25,4 +25,4 @@ jobs: workspace-folder: . container-runtime: podman container-id-label: ci=podman - test-command: 'make test' \ No newline at end of file + test-command: 'cd /workspaces/singularity && make test' \ No newline at end of file From c4fdf0258fe5d7af2f1bb3d4736b006afe87be0b Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Thu, 2 Oct 2025 22:56:33 +0200 Subject: [PATCH 27/39] fix mysql user --- .devcontainer/init-mysql.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.devcontainer/init-mysql.sh b/.devcontainer/init-mysql.sh index 94da58ca..878ce0f4 100755 --- a/.devcontainer/init-mysql.sh +++ b/.devcontainer/init-mysql.sh @@ -37,9 +37,12 @@ PASS=${MYSQL_PASSWORD:-singularity} mysql --socket="$SOCKET" "${MYSQL_ROOT_FLAGS[@]}" < Date: Fri, 3 Oct 2025 10:49:42 +0200 Subject: [PATCH 28/39] fix mysql fully --- .devcontainer/init-mysql.sh | 19 ++++++++++++------- .devcontainer/start-mysql.sh | 13 +++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/.devcontainer/init-mysql.sh b/.devcontainer/init-mysql.sh index 878ce0f4..669f4613 100755 --- a/.devcontainer/init-mysql.sh +++ b/.devcontainer/init-mysql.sh @@ -1,10 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -# If mysql client isn't present, exit quietly -if ! command -v mysql >/dev/null 2>&1; then - exit 0 -fi +# MariaDB client is required for init # Resolve socket path; default to user-owned socket SOCKET="${MYSQL_SOCKET:-${HOME}/.local/share/mysql/mysql.sock}" @@ -18,15 +15,18 @@ if [ -n "${MYSQL_ROOT_PASSWORD:-}" ]; then fi # Wait for server readiness (best effort) +echo "Waiting for MySQL server at socket: $SOCKET" for i in {1..60}; do - if mysqladmin --socket="$SOCKET" ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then + 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 ! mysqladmin --socket="$SOCKET" ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then +if ! mariadb-admin --socket="$SOCKET" ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then + echo "MySQL server not reachable, skipping init" exit 0 fi @@ -35,7 +35,8 @@ DB=${MYSQL_DATABASE:-singularity} USER=${MYSQL_USER:-singularity} PASS=${MYSQL_PASSWORD:-singularity} -mysql --socket="$SOCKET" "${MYSQL_ROOT_FLAGS[@]}" </dev/null 2>&1; then echo "MySQL server is ready" + echo "Socket exists at: ${SOCKET}" + echo "Continuing to init script..." exit 0 fi sleep 1 From 6b6445f4ad60c1b4683b0b3d91e38edd436c3b88 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 3 Oct 2025 11:18:58 +0200 Subject: [PATCH 29/39] final (?) fixes for DB connectivity! --- .devcontainer/devcontainer.json | 2 +- .devcontainer/init-mysql.sh | 6 ++-- .devcontainer/post-create.sh | 50 +++++++++++++++++++++++++++++++++ .devcontainer/start-mysql.sh | 20 ++++--------- .devcontainer/start-postgres.sh | 17 +++++------ util/testutil/testutils.go | 6 +++- 6 files changed, 70 insertions(+), 31 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f0e2ff23..f2c092ac 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -27,7 +27,7 @@ "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 && ${containerWorkspaceFolder}/.devcontainer/init-mysql.sh'", + "postStartCommand": "/bin/bash -lc '${containerWorkspaceFolder}/.devcontainer/start-postgres.sh && ${containerWorkspaceFolder}/.devcontainer/start-mysql.sh'", "remoteUser": "vscode", "containerEnv": { "GOPATH": "/home/vscode/go", diff --git a/.devcontainer/init-mysql.sh b/.devcontainer/init-mysql.sh index 669f4613..b9e3f1af 100755 --- a/.devcontainer/init-mysql.sh +++ b/.devcontainer/init-mysql.sh @@ -26,8 +26,8 @@ done # Bail if still unreachable if ! mariadb-admin --socket="$SOCKET" ping "${MYSQL_ROOT_FLAGS[@]}" >/dev/null 2>&1; then - echo "MySQL server not reachable, skipping init" - exit 0 + echo "MySQL server not reachable, init failed" + exit 1 fi # Create database and user idempotently (MySQL 8+ supports IF NOT EXISTS for users) @@ -48,8 +48,6 @@ GRANT ALL PRIVILEGES ON \`${DB}\`.* TO '${USER}'@'%'; FLUSH PRIVILEGES; SQL -echo "Checking created users:" -mariadb --socket="$SOCKET" "${MYSQL_ROOT_FLAGS[@]}" -e "SELECT user, host, plugin, authentication_string FROM mysql.user WHERE user='${USER}' OR user='root';" echo "MySQL init completed successfully" ## No marker file; script can run safely on every start diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 2ac5dda3..5d270f03 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -6,4 +6,54 @@ 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 and databases +echo "Creating database users and databases..." + +# Postgres setup +psql -h localhost -p 55432 -d postgres -c "CREATE USER singularity WITH SUPERUSER;" +createdb -h localhost -p 55432 -O singularity singularity + +# MySQL setup +mariadb --socket=/home/vscode/.local/share/mysql/mysql.sock -uroot </dev/null -fi - -# If already running, exit -if [ -S "${SOCKET}" ] && mysqladmin --socket="${SOCKET}" ping >/dev/null 2>&1; then +# 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 \ @@ -36,12 +28,10 @@ nohup mariadbd \ --log-error="${LOG_FILE}" \ >/dev/null 2>&1 & -# Wait for MySQL to be ready (log-based + socket existence) +# 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" - echo "Socket exists at: ${SOCKET}" - echo "Continuing to init script..." exit 0 fi sleep 1 diff --git a/.devcontainer/start-postgres.sh b/.devcontainer/start-postgres.sh index af02d3e6..b90cb1a8 100755 --- a/.devcontainer/start-postgres.sh +++ b/.devcontainer/start-postgres.sh @@ -1,24 +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}" -mkdir -p "$PGDATA_DIR" "$PGSOCK_DIR" - -if [ ! -f "$PGDATA_DIR/PG_VERSION" ]; then - "${PG_BIN_DIR}/initdb" -D "$PGDATA_DIR" --auth trust --auth-local trust --auth-host trust - echo "listen_addresses='localhost'" >> "$PGDATA_DIR/postgresql.conf" - { - echo 'host all all 127.0.0.1/32 trust' - echo 'host all all ::1/128 trust' - echo 'local all all trust' - } >> "$PGDATA_DIR/pg_hba.conf" +# 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 diff --git a/util/testutil/testutils.go b/util/testutil/testutils.go index fa56a1f8..8d96222b 100644 --- a/util/testutil/testutils.go +++ b/util/testutil/testutils.go @@ -96,7 +96,11 @@ func getTestDB(t *testing.T, dialect string) (db *gorm.DB, closer io.Closer, con connStr = "mysql://singularity:singularity@tcp(localhost:3306)/singularity?parseTime=true" } case "postgres": - connStr = "postgres://postgres@localhost:5432/postgres?sslmode=disable" + if pgPort := os.Getenv("PGPORT"); pgPort != "" { + connStr = "postgres://singularity@localhost:" + pgPort + "/singularity?sslmode=disable" + } else { + connStr = "postgres://singularity@localhost:5432/singularity?sslmode=disable" + } default: require.Fail(t, "Unsupported dialect: "+dialect) } From 97954bd74d35733a142f49682c658dc42e94b622 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 3 Oct 2025 15:37:05 +0000 Subject: [PATCH 30/39] add create db role --- .devcontainer/post-create.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 5d270f03..31b35c96 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -39,7 +39,7 @@ echo "Starting database servers..." echo "Creating database users and databases..." # Postgres setup -psql -h localhost -p 55432 -d postgres -c "CREATE USER singularity WITH SUPERUSER;" +psql -h localhost -p 55432 -d postgres -c "CREATE USER singularity WITH SUPERUSER CREATEDB CREATEROLE LOGIN;" createdb -h localhost -p 55432 -O singularity singularity # MySQL setup From 20c95cface307e99eff8b6ccb3ddcace17b0cec3 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Fri, 3 Oct 2025 17:59:22 +0200 Subject: [PATCH 31/39] ok we have working DB tests --- .devcontainer/post-create.sh | 8 +-- util/testutil/testutils.go | 96 ++++++++++++++++++++++-------------- 2 files changed, 61 insertions(+), 43 deletions(-) diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 31b35c96..88c74e34 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -35,22 +35,18 @@ echo "Starting database servers..." .devcontainer/start-postgres.sh .devcontainer/start-mysql.sh -# Create users and databases -echo "Creating database users and databases..." +# 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;" -createdb -h localhost -p 55432 -O singularity singularity # MySQL setup mariadb --socket=/home/vscode/.local/share/mysql/mysql.sock -uroot < Date: Tue, 14 Oct 2025 10:46:36 +0000 Subject: [PATCH 32/39] fix job selection logic - AND takes precedence over OR in MySQL (https://dev.mysql.com/doc/refman/8.4/en/operator-precedence.html) which does not appear to be the intended logic --- service/datasetworker/find.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/service/datasetworker/find.go b/service/datasetworker/find.go index b8077a89..367c6915 100644 --- a/service/datasetworker/find.go +++ b/service/datasetworker/find.go @@ -30,11 +30,11 @@ func (w *Thread) findJob(ctx context.Context, typesOrdered []model.JobType) (*mo } var job model.Job for _, jobType := range typesOrdered { - err := database.DoRetry(ctx, func() error { - return db.Transaction(func(db *gorm.DB) error { - err := db.Preload("Attachment.Preparation.OutputStorages").Preload("Attachment.Storage"). - Where("type = ? AND state = ? OR (state = ? AND worker_id is null)", jobType, model.Ready, model.Processing). - First(&job).Error + err := database.DoRetry(ctx, func() error { + return db.Transaction(func(db *gorm.DB) error { + err := db.Preload("Attachment.Preparation.OutputStorages").Preload("Attachment.Storage"). + Where("type = ? AND (state = ? OR (state = ? AND worker_id IS NULL))", jobType, model.Ready, model.Processing). + First(&job).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { job.ID = 0 From 45eda3d3e4ea65e672ee47e2dd723a6407cbb052 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Tue, 14 Oct 2025 10:50:22 +0000 Subject: [PATCH 33/39] suppress missing table noise in tests --- database/util.go | 8 +++++++- util/testutil/testutils.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/database/util.go b/database/util.go index fd3ae43e..88aa5f44 100644 --- a/database/util.go +++ b/database/util.go @@ -61,7 +61,13 @@ func (d *databaseLogger) Trace(ctx context.Context, begin time.Time, fc func() ( sql = "[SLOW!] " + sql } if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) && !strings.Contains(err.Error(), sqlSerializationFailure) { - lvl = logging.LevelError + // Demote noisy missing-table errors during test setup/teardown + emsg := err.Error() + if strings.Contains(emsg, "no such table") || strings.Contains(emsg, "does not exist") || strings.Contains(emsg, "doesn't exist") { + lvl = logging.LevelDebug + } else { + lvl = logging.LevelError + } } // Uncomment for logging everything in testing diff --git a/util/testutil/testutils.go b/util/testutil/testutils.go index 1a242c46..4842d6db 100644 --- a/util/testutil/testutils.go +++ b/util/testutil/testutils.go @@ -208,6 +208,36 @@ func doOne(t *testing.T, backend string, testFunc func(ctx context.Context, t *t err := model.GetMigrator(db).Migrate() require.NoError(t, err) + // Clear any existing data from tables with unique constraints + tables := []string{ + "output_attachments", + "source_attachments", + "storages", + "wallets", + "deal_schedules", + "preparations", + } + + // Get DB type from connection string + isPostgres := strings.HasPrefix(connStr, "postgres:") + for _, table := range tables { + var err error + if isPostgres { + err = db.Exec("TRUNCATE TABLE " + table + " CASCADE").Error + } else { + err = db.Exec("DELETE FROM " + table).Error + } + if err != nil { + emsg := err.Error() + // Suppress noisy logs when tables don't exist yet across backends + if strings.Contains(emsg, "no such table") || strings.Contains(emsg, "does not exist") || strings.Contains(emsg, "doesn't exist") { + continue + } + t.Logf("Warning: Failed to clear table %s: %v", table, err) + // Don't fail the test for other errors either + } + } + t.Run(backend, func(t *testing.T) { testFunc(ctx, t, db) }) From 7280200851c86d9a4a9d6e7b63132668f879b7d0 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Tue, 14 Oct 2025 11:03:53 +0000 Subject: [PATCH 34/39] disable DAG generation during duplicate piece test --- cmd/functional_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/functional_test.go b/cmd/functional_test.go index 9867d033..faea9f32 100644 --- a/cmd/functional_test.go +++ b/cmd/functional_test.go @@ -513,7 +513,7 @@ func TestNoDuplicatedOutput(t *testing.T) { // run the dataset worker. If multiple workers try to work on the same // job, then this will return fail because a previous worker will have // removed files. - _, _, err = runner.Run(ctx, "singularity run dataset-worker --exit-on-complete=true --exit-on-error=true --concurrency=8") + _, _, err = runner.Run(ctx, "singularity run dataset-worker --exit-on-complete=true --exit-on-error=true --concurrency=8 --enable-dag=false") require.NoError(t, err) // Check output to make sure is has some CAR files From cbc6cb20297130d3b6ac07bb3a3f0ac863cf2a86 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Tue, 14 Oct 2025 11:06:04 +0000 Subject: [PATCH 35/39] resolve 'record changed since last read' errors --- database/util.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/database/util.go b/database/util.go index 88aa5f44..062b23b6 100644 --- a/database/util.go +++ b/database/util.go @@ -99,5 +99,10 @@ func OpenFromCLI(c *cli.Context) (*gorm.DB, io.Closer, error) { func retryOn(err error) bool { emsg := err.Error() - return strings.Contains(emsg, sqlSerializationFailure) || strings.Contains(emsg, "database is locked") || strings.Contains(emsg, "database table is locked") + return strings.Contains(emsg, sqlSerializationFailure) || + strings.Contains(emsg, "database is locked") || + strings.Contains(emsg, "database table is locked") || + // MySQL/InnoDB serialization conflict + strings.Contains(emsg, "Record has changed since last read") || + strings.Contains(emsg, "Error 1020 (HY000)") } From 50f0434b0d05eb4f0d5737309b9a305c0e77de74 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Tue, 14 Oct 2025 12:10:05 +0000 Subject: [PATCH 36/39] use v2 action, remove stray file --- .github/workflows/devcontainer-podman.yml | 65 ++++++++++++++++++++--- .github/workflows/test-devcontainer.yaml | 8 --- 2 files changed, 58 insertions(+), 15 deletions(-) delete mode 100644 .github/workflows/test-devcontainer.yaml diff --git a/.github/workflows/devcontainer-podman.yml b/.github/workflows/devcontainer-podman.yml index 3d80c1fd..f72283b9 100644 --- a/.github/workflows/devcontainer-podman.yml +++ b/.github/workflows/devcontainer-podman.yml @@ -2,27 +2,78 @@ name: CI (Podman Devcontainer) on: push: - branches: [ local/devcontainer ] + branches: [ main, develop ] pull_request: - branches: [ local/devcontainer ] + 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: - test: + 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@v1 + uses: parkan/github-actions/setup-podman-docker@v2 with: disable-docker: true cache-storage: false # Disabled until cache issues resolved - - name: Run Devcontainer Tests - uses: parkan/github-actions/devcontainer-test@v1 + - name: Build devcontainer + id: build + uses: parkan/github-actions/devcontainer-build@v2 with: workspace-folder: . container-runtime: podman container-id-label: ci=podman - test-command: 'cd /workspaces/singularity && make test' \ No newline at end of file + + - 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 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: 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 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 + uses: parkan/github-actions/devcontainer-exec@v2 + with: + container-id: ${{ steps.build.outputs.container-id }} + command: 'cd /workspaces/singularity && go build ./...' + 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 diff --git a/.github/workflows/test-devcontainer.yaml b/.github/workflows/test-devcontainer.yaml deleted file mode 100644 index 867924f2..00000000 --- a/.github/workflows/test-devcontainer.yaml +++ /dev/null @@ -1,8 +0,0 @@ -name: disabled (replaced by Podman devcontainer workflow) -on: - workflow_call: -jobs: - skip: - runs-on: ubuntu-latest - steps: - - run: echo "This workflow is disabled. See devcontainer-podman.yml." \ No newline at end of file From 71e0bb6095f4a18b888ce3a90be9b6782246f728 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Tue, 14 Oct 2025 12:21:27 +0000 Subject: [PATCH 37/39] reorder steps for fast fail --- .github/workflows/devcontainer-podman.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/devcontainer-podman.yml b/.github/workflows/devcontainer-podman.yml index f72283b9..e7f73d74 100644 --- a/.github/workflows/devcontainer-podman.yml +++ b/.github/workflows/devcontainer-podman.yml @@ -36,11 +36,11 @@ jobs: container-runtime: podman container-id-label: ci=podman - - name: Run tests + - name: Check formatting uses: parkan/github-actions/devcontainer-exec@v2 with: container-id: ${{ steps.build.outputs.container-id }} - command: 'cd /workspaces/singularity && go test -v ./...' + command: 'cd /workspaces/singularity && gofmt -l .' container-runtime: podman - name: Run go vet @@ -50,25 +50,25 @@ jobs: command: 'cd /workspaces/singularity && go vet ./...' container-runtime: podman - - name: Check formatting + - name: Run staticcheck uses: parkan/github-actions/devcontainer-exec@v2 with: container-id: ${{ steps.build.outputs.container-id }} - command: 'cd /workspaces/singularity && gofmt -l .' + command: 'cd /workspaces/singularity && staticcheck ./...' container-runtime: podman - - name: Run staticcheck + - name: Build uses: parkan/github-actions/devcontainer-exec@v2 with: container-id: ${{ steps.build.outputs.container-id }} - command: 'cd /workspaces/singularity && staticcheck ./...' + command: 'cd /workspaces/singularity && go build ./...' container-runtime: podman - - name: Build + - name: Run tests uses: parkan/github-actions/devcontainer-exec@v2 with: container-id: ${{ steps.build.outputs.container-id }} - command: 'cd /workspaces/singularity && go build ./...' + command: 'cd /workspaces/singularity && go test -v ./...' container-runtime: podman - name: Cleanup From 7fee74d51f9730b41609ae1312c8b40a178108b9 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Tue, 14 Oct 2025 12:25:21 +0000 Subject: [PATCH 38/39] add steps that make sense --- .github/workflows/devcontainer-podman.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/devcontainer-podman.yml b/.github/workflows/devcontainer-podman.yml index e7f73d74..84934b1e 100644 --- a/.github/workflows/devcontainer-podman.yml +++ b/.github/workflows/devcontainer-podman.yml @@ -36,6 +36,14 @@ jobs: 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/swagger@v0.30.5 && go generate ./client/swagger/...' + container-runtime: podman + - name: Check formatting uses: parkan/github-actions/devcontainer-exec@v2 with: @@ -57,11 +65,11 @@ jobs: command: 'cd /workspaces/singularity && staticcheck ./...' container-runtime: podman - - name: Build + - name: Build binary uses: parkan/github-actions/devcontainer-exec@v2 with: container-id: ${{ steps.build.outputs.container-id }} - command: 'cd /workspaces/singularity && go build ./...' + command: 'cd /workspaces/singularity && go build -o singularity .' container-runtime: podman - name: Run tests @@ -71,6 +79,13 @@ jobs: 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 From 249cab7944dbd8d8c39100835fb1909d054a9c66 Mon Sep 17 00:00:00 2001 From: Arkadiy Kukarkin Date: Wed, 15 Oct 2025 15:30:58 +0200 Subject: [PATCH 39/39] remove heavyweight unified workflows --- .github/workflows/go-check-config.json | 3 - .github/workflows/go-check.yml | 35 ---------- .github/workflows/go-test-config.json | 3 - .github/workflows/go-test.yml | 18 ----- .github/workflows/integration-test.yml | 93 -------------------------- 5 files changed, 152 deletions(-) delete mode 100644 .github/workflows/go-check-config.json delete mode 100644 .github/workflows/go-check.yml delete mode 100644 .github/workflows/go-test-config.json delete mode 100644 .github/workflows/go-test.yml delete mode 100644 .github/workflows/integration-test.yml diff --git a/.github/workflows/go-check-config.json b/.github/workflows/go-check-config.json deleted file mode 100644 index 4b37308d..00000000 --- a/.github/workflows/go-check-config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "gogenerate": true -} diff --git a/.github/workflows/go-check.yml b/.github/workflows/go-check.yml deleted file mode 100644 index 826de5c2..00000000 --- a/.github/workflows/go-check.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Go Checks - -on: - pull_request: - push: - branches: ["main"] - 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: - go-check: - uses: ipdxco/unified-github-workflows/.github/workflows/go-check.yml@v1.0.22 - - staticcheck: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: "1.21" - - - name: Install staticcheck - run: go install honnef.co/go/tools/cmd/staticcheck@latest - - - name: Run staticcheck - run: staticcheck ./... diff --git a/.github/workflows/go-test-config.json b/.github/workflows/go-test-config.json deleted file mode 100644 index 209dca21..00000000 --- a/.github/workflows/go-test-config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "skip32bit": true -} diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml deleted file mode 100644 index 92b1383b..00000000 --- a/.github/workflows/go-test.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Go Test - -on: - pull_request: - push: - branches: ["main"] - 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: - go-test: - uses: ipdxco/unified-github-workflows/.github/workflows/go-test.yml@v1.0.22 diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml deleted file mode 100644 index 1b53cbf0..00000000 --- a/.github/workflows/integration-test.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Integration Tests - -on: - pull_request: - paths: - # Run when integration test files are modified - - 'cmd/auto_prep_deals_integration_test.go' - - 'cmd/*_integration_test.go' - - # Run when related source files are modified - - 'cmd/deal/**' - - 'cmd/dataset/**' - - 'cmd/storage/**' - - 'cmd/wallet/**' - - 'cmd/run/**' - - 'cmd/job/**' - - # Run when core functionality changes - - 'handler/deal/**' - - 'handler/dataset/**' - - 'handler/storage/**' - - 'handler/wallet/**' - - 'handler/job/**' - - # Run when worker and scheduler code changes - - 'worker/**' - - 'scheduler/**' - - # Run when models change - - 'model/**' - - # Run when database migrations change - - 'migrate/**' - - # Run when workflow itself changes - - '.github/workflows/integration-test.yml' - - push: - branches: ["main"] - paths: - # Same paths as pull_request - - 'cmd/auto_prep_deals_integration_test.go' - - 'cmd/*_integration_test.go' - - 'cmd/deal/**' - - 'cmd/dataset/**' - - 'cmd/storage/**' - - 'cmd/wallet/**' - - 'cmd/run/**' - - 'cmd/job/**' - - 'handler/deal/**' - - 'handler/dataset/**' - - 'handler/storage/**' - - 'handler/wallet/**' - - 'handler/job/**' - - 'worker/**' - - 'scheduler/**' - - 'model/**' - - 'migrate/**' - - '.github/workflows/integration-test.yml' - - 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: - integration-test: - runs-on: ubuntu-latest - timeout-minutes: 30 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: "1.21" - - - name: Install dependencies - run: go mod download - - - name: Run integration tests - run: | - # Run only integration tests with verbose output - go test -v -timeout 20m -run "Integration" ./cmd/... - env: - # Set any required environment variables for integration tests - SINGULARITY_TEST_INTEGRATION: "true" \ No newline at end of file