fix(ci): fix postgres TCP setup and truncateAll superuser error
- Use apt-get install + configure listen_addresses + md5 auth in pg_hba so psql can connect via 127.0.0.1 (not just Unix socket) - Use pg_ctlcluster restart after config changes + wait for pg_isready - Replace session_replication_role (requires superuser) with a single TRUNCATE ... CASCADE which handles FK deps without elevated privileges - All 3 integration tests now pass in CI (act + Gitea Actions) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #136.
This commit is contained in:
+10
-11
@@ -44,26 +44,25 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
sudo apt-get update -qq && sudo apt-get install -y -qq postgresql > /dev/null
|
sudo apt-get update -qq && sudo apt-get install -y -qq postgresql > /dev/null
|
||||||
PG_VER=$(ls /etc/postgresql/)
|
PG_VER=$(ls /etc/postgresql/)
|
||||||
sudo pg_ctlcluster $PG_VER main start
|
sudo sed -i "s/^#*listen_addresses\s*=.*/listen_addresses = '127.0.0.1'/" /etc/postgresql/$PG_VER/main/postgresql.conf
|
||||||
|
echo "host all all 127.0.0.1/32 md5" | sudo tee -a /etc/postgresql/$PG_VER/main/pg_hba.conf
|
||||||
|
sudo pg_ctlcluster $PG_VER main restart
|
||||||
|
until sudo -u postgres pg_isready -h 127.0.0.1; do sleep 1; done
|
||||||
sudo -u postgres psql -c "CREATE USER test WITH PASSWORD 'test';"
|
sudo -u postgres psql -c "CREATE USER test WITH PASSWORD 'test';"
|
||||||
sudo -u postgres psql -c "CREATE DATABASE polympr_test OWNER test;"
|
sudo -u postgres psql -c "CREATE DATABASE polympr_test OWNER test;"
|
||||||
sudo -u postgres psql -d polympr_test -c "GRANT ALL ON SCHEMA public TO test;"
|
sudo -u postgres psql -d polympr_test -c "GRANT ALL ON SCHEMA public TO test;"
|
||||||
|
|
||||||
|
- name: Apply migrations
|
||||||
|
run: |
|
||||||
|
sed 's/--> statement-breakpoint/;/g' databases/migrations/0000_square_jetstream.sql | \
|
||||||
|
PGPASSWORD=test psql -h 127.0.0.1 -U test -d polympr_test
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm install --ignore-scripts && deno install
|
run: npm install --ignore-scripts && deno install
|
||||||
|
|
||||||
- name: Apply migrations
|
|
||||||
env:
|
|
||||||
POSTGRES_HOST: localhost
|
|
||||||
POSTGRES_PORT: 5432
|
|
||||||
POSTGRES_USER: test
|
|
||||||
POSTGRES_PASS: test
|
|
||||||
POSTGRES_DB: polympr_test
|
|
||||||
run: node_modules/.bin/drizzle-kit migrate
|
|
||||||
|
|
||||||
- name: Run integration tests
|
- name: Run integration tests
|
||||||
env:
|
env:
|
||||||
POSTGRES_HOST: localhost
|
POSTGRES_HOST: 127.0.0.1
|
||||||
POSTGRES_PORT: 5432
|
POSTGRES_PORT: 5432
|
||||||
POSTGRES_USER: test
|
POSTGRES_USER: test
|
||||||
POSTGRES_PASS: test
|
POSTGRES_PASS: test
|
||||||
|
|||||||
@@ -18,29 +18,15 @@ function createTestPool(): pg.Pool {
|
|||||||
user: Deno.env.get("POSTGRES_USER") ?? "test",
|
user: Deno.env.get("POSTGRES_USER") ?? "test",
|
||||||
password: Deno.env.get("POSTGRES_PASS") ?? "test",
|
password: Deno.env.get("POSTGRES_PASS") ?? "test",
|
||||||
database: Deno.env.get("POSTGRES_DB") ?? "polympr_test",
|
database: Deno.env.get("POSTGRES_DB") ?? "polympr_test",
|
||||||
|
ssl: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const testPool = createTestPool();
|
export const testPool = createTestPool();
|
||||||
export const testDb = drizzle(testPool, { schema });
|
export const testDb = drizzle(testPool, { schema });
|
||||||
|
|
||||||
// Ordre de truncate respectant les FK (enfants avant parents)
|
const ALL_TABLES =
|
||||||
const TRUNCATE_ORDER = [
|
'"mobility","ajustements","notes","ue_modules","enseignements","role_permissions","students","users","modules","ues","promotions","permissions","roles"';
|
||||||
"mobility",
|
|
||||||
"ajustements",
|
|
||||||
"notes",
|
|
||||||
"ue_modules",
|
|
||||||
"enseignements",
|
|
||||||
"role_permissions",
|
|
||||||
"students",
|
|
||||||
"ue_modules",
|
|
||||||
"users",
|
|
||||||
"modules",
|
|
||||||
"ues",
|
|
||||||
"promotions",
|
|
||||||
"permissions",
|
|
||||||
"roles",
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vide toutes les tables dans le bon ordre.
|
* Vide toutes les tables dans le bon ordre.
|
||||||
@@ -49,12 +35,9 @@ const TRUNCATE_ORDER = [
|
|||||||
export async function truncateAll(): Promise<void> {
|
export async function truncateAll(): Promise<void> {
|
||||||
const client = await testPool.connect();
|
const client = await testPool.connect();
|
||||||
try {
|
try {
|
||||||
// Désactiver les FK temporairement pour simplifier
|
await client.query(
|
||||||
await client.query("SET session_replication_role = replica");
|
`TRUNCATE TABLE ${ALL_TABLES} RESTART IDENTITY CASCADE`,
|
||||||
for (const table of TRUNCATE_ORDER) {
|
);
|
||||||
await client.query(`TRUNCATE TABLE "${table}" RESTART IDENTITY CASCADE`);
|
|
||||||
}
|
|
||||||
await client.query("SET session_replication_role = DEFAULT");
|
|
||||||
} finally {
|
} finally {
|
||||||
client.release();
|
client.release();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { assertEquals, assertExists } from "@std/assert";
|
||||||
|
import {
|
||||||
|
closeTestPool,
|
||||||
|
seedRoles,
|
||||||
|
seedUsers,
|
||||||
|
testDb,
|
||||||
|
truncateAll,
|
||||||
|
} from "../helpers/db_integration.ts";
|
||||||
|
import { users } from "$root/databases/schema.ts";
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: "integration: GET /users - DB round trip",
|
||||||
|
async fn() {
|
||||||
|
await truncateAll();
|
||||||
|
|
||||||
|
const [role] = await seedRoles([{ nom: "employee" }]);
|
||||||
|
await seedUsers([
|
||||||
|
{ id: "dupont.jean", nom: "Dupont", prenom: "Jean", idRole: role.id },
|
||||||
|
{ id: "martin.alice", nom: "Martin", prenom: "Alice", idRole: role.id },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const rows = await testDb.select().from(users);
|
||||||
|
assertEquals(rows.length, 2);
|
||||||
|
assertExists(rows.find((u) => u.id === "dupont.jean"));
|
||||||
|
},
|
||||||
|
sanitizeResources: false,
|
||||||
|
sanitizeOps: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: "integration: INSERT user and retrieve by id",
|
||||||
|
async fn() {
|
||||||
|
await truncateAll();
|
||||||
|
|
||||||
|
const [role] = await seedRoles([{ nom: "admin" }]);
|
||||||
|
const [created] = await testDb.insert(users).values({
|
||||||
|
id: "durand.claire",
|
||||||
|
nom: "Durand",
|
||||||
|
prenom: "Claire",
|
||||||
|
idRole: role.id,
|
||||||
|
}).returning();
|
||||||
|
|
||||||
|
assertExists(created);
|
||||||
|
assertEquals(created.id, "durand.claire");
|
||||||
|
assertEquals(created.nom, "Durand");
|
||||||
|
},
|
||||||
|
sanitizeResources: false,
|
||||||
|
sanitizeOps: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: "integration: cleanup - close pool",
|
||||||
|
async fn() {
|
||||||
|
await closeTestPool();
|
||||||
|
},
|
||||||
|
sanitizeResources: false,
|
||||||
|
sanitizeOps: false,
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user