Compare commits
10 Commits
master
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4d5216666 | ||
|
|
7b22d562bc | ||
|
|
063287aa18 | ||
|
|
873dd5c95f | ||
|
|
b49c5aa463 | ||
|
|
4e28b99799 | ||
|
|
d1465199d8 | ||
|
|
c6696d6a77 | ||
|
|
17885b5438 | ||
|
|
1f5d184b11 |
@ -6,7 +6,9 @@ exports.up = function (knex) {
|
|||||||
.createTable("domain_expiry", (table) => {
|
.createTable("domain_expiry", (table) => {
|
||||||
table.increments("id");
|
table.increments("id");
|
||||||
table.datetime("last_check");
|
table.datetime("last_check");
|
||||||
table.text("domain").unique().notNullable();
|
// Use VARCHAR(255) for MySQL/MariaDB compatibility with unique constraint
|
||||||
|
// Maximum domain name length is 253 characters (255 octets on the wire)
|
||||||
|
table.string("domain", 255).unique().notNullable();
|
||||||
table.datetime("expiry");
|
table.datetime("expiry");
|
||||||
table.integer("last_expiry_notification_sent").defaultTo(null);
|
table.integer("last_expiry_notification_sent").defaultTo(null);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
// Ensure domain column is VARCHAR(255) across all database types.
|
||||||
|
// This migration ensures MySQL, SQLite, and MariaDB have consistent column type,
|
||||||
|
// even if a user installed 2.1.0-beta.0 or 2.1.0-beta.1 which had TEXT type for this column.
|
||||||
|
// Maximum domain name length is 253 characters (255 octets on the wire).
|
||||||
|
// Note: The unique constraint is already present from the original migration.
|
||||||
|
exports.up = function (knex) {
|
||||||
|
return knex.schema.alterTable("domain_expiry", function (table) {
|
||||||
|
table.string("domain", 255).notNullable().alter();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = function (knex) {
|
||||||
|
// No rollback needed - keeping VARCHAR(255) is the correct state
|
||||||
|
};
|
||||||
58
package-lock.json
generated
58
package-lock.json
generated
@ -103,6 +103,7 @@
|
|||||||
"@testcontainers/hivemq": "^10.13.1",
|
"@testcontainers/hivemq": "^10.13.1",
|
||||||
"@testcontainers/mariadb": "^10.13.0",
|
"@testcontainers/mariadb": "^10.13.0",
|
||||||
"@testcontainers/mssqlserver": "^10.28.0",
|
"@testcontainers/mssqlserver": "^10.28.0",
|
||||||
|
"@testcontainers/mysql": "^11.11.0",
|
||||||
"@testcontainers/postgresql": "^11.9.0",
|
"@testcontainers/postgresql": "^11.9.0",
|
||||||
"@testcontainers/rabbitmq": "^10.13.2",
|
"@testcontainers/rabbitmq": "^10.13.2",
|
||||||
"@types/bootstrap": "~5.1.9",
|
"@types/bootstrap": "~5.1.9",
|
||||||
@ -5665,6 +5666,63 @@
|
|||||||
"testcontainers": "^10.28.0"
|
"testcontainers": "^10.28.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@testcontainers/mysql": {
|
||||||
|
"version": "11.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@testcontainers/mysql/-/mysql-11.11.0.tgz",
|
||||||
|
"integrity": "sha512-2EfFhUDEvEdwBwez+F/NhqP+h2rFzLzHYbRX0N/9/Lgdlq8TbsYWZ9SaWL9V0f1FWX89XnyZrT3i/j7m8MIESg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"testcontainers": "^11.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@testcontainers/mysql/node_modules/docker-compose": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-7Gevk/5eGD50+eMD+XDnFnOrruFkL0kSd7jEG4cjmqweDSUhB7i0g8is/nBdVpl+Bx338SqIB2GLKm32M+Vs6g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"yaml": "^2.2.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@testcontainers/mysql/node_modules/testcontainers": {
|
||||||
|
"version": "11.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-11.11.0.tgz",
|
||||||
|
"integrity": "sha512-nKTJn3n/gkyGg/3SVkOwX+isPOGSHlfI+CWMobSmvQrsj7YW01aWvl2pYIfV4LMd+C8or783yYrzKSK2JlP+Qw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@balena/dockerignore": "^1.0.2",
|
||||||
|
"@types/dockerode": "^3.3.47",
|
||||||
|
"archiver": "^7.0.1",
|
||||||
|
"async-lock": "^1.4.1",
|
||||||
|
"byline": "^5.0.0",
|
||||||
|
"debug": "^4.4.3",
|
||||||
|
"docker-compose": "^1.3.0",
|
||||||
|
"dockerode": "^4.0.9",
|
||||||
|
"get-port": "^7.1.0",
|
||||||
|
"proper-lockfile": "^4.1.2",
|
||||||
|
"properties-reader": "^2.3.0",
|
||||||
|
"ssh-remote-port-forward": "^1.0.4",
|
||||||
|
"tar-fs": "^3.1.1",
|
||||||
|
"tmp": "^0.2.5",
|
||||||
|
"undici": "^7.16.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@testcontainers/mysql/node_modules/undici": {
|
||||||
|
"version": "7.18.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici/-/undici-7.18.2.tgz",
|
||||||
|
"integrity": "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.18.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@testcontainers/postgresql": {
|
"node_modules/@testcontainers/postgresql": {
|
||||||
"version": "11.11.0",
|
"version": "11.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-11.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-11.11.0.tgz",
|
||||||
|
|||||||
@ -164,6 +164,7 @@
|
|||||||
"@testcontainers/hivemq": "^10.13.1",
|
"@testcontainers/hivemq": "^10.13.1",
|
||||||
"@testcontainers/mariadb": "^10.13.0",
|
"@testcontainers/mariadb": "^10.13.0",
|
||||||
"@testcontainers/mssqlserver": "^10.28.0",
|
"@testcontainers/mssqlserver": "^10.28.0",
|
||||||
|
"@testcontainers/mysql": "^11.11.0",
|
||||||
"@testcontainers/postgresql": "^11.9.0",
|
"@testcontainers/postgresql": "^11.9.0",
|
||||||
"@testcontainers/rabbitmq": "^10.13.2",
|
"@testcontainers/rabbitmq": "^10.13.2",
|
||||||
"@types/bootstrap": "~5.1.9",
|
"@types/bootstrap": "~5.1.9",
|
||||||
|
|||||||
@ -2,6 +2,7 @@ const { describe, test } = require("node:test");
|
|||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const { GenericContainer, Wait } = require("testcontainers");
|
const { GenericContainer, Wait } = require("testcontainers");
|
||||||
|
const { MySqlContainer } = require("@testcontainers/mysql");
|
||||||
|
|
||||||
describe("Database Migration", () => {
|
describe("Database Migration", () => {
|
||||||
test("SQLite migrations run successfully from fresh database", async () => {
|
test("SQLite migrations run successfully from fresh database", async () => {
|
||||||
@ -130,4 +131,68 @@ describe("Database Migration", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"MySQL migrations run successfully from fresh database",
|
||||||
|
{
|
||||||
|
skip:
|
||||||
|
!!process.env.CI &&
|
||||||
|
(process.platform !== "linux" || process.arch !== "x64"),
|
||||||
|
},
|
||||||
|
async () => {
|
||||||
|
// Start MySQL 8.0 container (the version mentioned in the issue)
|
||||||
|
const mysqlContainer = await new MySqlContainer("mysql:8.0")
|
||||||
|
.withStartupTimeout(120000)
|
||||||
|
.start();
|
||||||
|
|
||||||
|
const knex = require("knex");
|
||||||
|
const knexInstance = knex({
|
||||||
|
client: "mysql2",
|
||||||
|
connection: {
|
||||||
|
host: mysqlContainer.getHost(),
|
||||||
|
port: mysqlContainer.getPort(),
|
||||||
|
user: mysqlContainer.getUsername(),
|
||||||
|
password: mysqlContainer.getUserPassword(),
|
||||||
|
database: mysqlContainer.getDatabase(),
|
||||||
|
connectTimeout: 60000,
|
||||||
|
},
|
||||||
|
pool: {
|
||||||
|
min: 0,
|
||||||
|
max: 10,
|
||||||
|
acquireTimeoutMillis: 60000,
|
||||||
|
idleTimeoutMillis: 60000,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Setup R (redbean) with knex instance like production code does
|
||||||
|
const { R } = require("redbean-node");
|
||||||
|
R.setup(knexInstance);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Use production code to initialize MySQL tables
|
||||||
|
const { createTables } = require("../../db/knex_init_db.js");
|
||||||
|
await createTables();
|
||||||
|
|
||||||
|
// Run all migrations like production code does
|
||||||
|
await R.knex.migrate.latest({
|
||||||
|
directory: path.join(__dirname, "../../db/knex_migrations")
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test passes if migrations complete successfully without errors
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
// Clean up
|
||||||
|
try {
|
||||||
|
await R.knex.destroy();
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore cleanup errors
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await mysqlContainer.stop();
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore cleanup errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user