Fixing images to use a locked SHA, this means that we shouldn't have issues with CI breaking due to using images which are receiving updates (we've experienced two CI breakages due to MariaDB and MS-SQL updates).

This commit is contained in:
mike12345567 2024-07-24 16:31:13 +01:00
parent fd9296cab7
commit e9d3c48ff4
11 changed files with 57 additions and 21 deletions

View File

@ -108,7 +108,7 @@ jobs:
- name: Pull testcontainers images - name: Pull testcontainers images
run: | run: |
docker pull testcontainers/ryuk:0.5.1 & docker pull testcontainers/ryuk:0.5.1 &
docker pull budibase/couchdb:v3.2.1-sqs & docker pull budibase/couchdb:v3.3.3 &
docker pull redis & docker pull redis &
wait $(jobs -p) wait $(jobs -p)
@ -162,17 +162,22 @@ jobs:
node-version: 20.x node-version: 20.x
cache: yarn cache: yarn
- name: Load dotenv
run: |
npm install -g dotenv-cli &
dotenv -e packages/server/datasource-sha.env -- env > $GITHUB_ENV
- name: Pull testcontainers images - name: Pull testcontainers images
run: | run: |
docker pull mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04 & docker pull mcr.microsoft.com/mssql/server@${{ env.MSSQL_SHA }} &
docker pull mysql:8.3 & docker pull mysql@${{ env.MYSQL_SHA }} &
docker pull postgres:16.1-bullseye & docker pull postgres@${{ env.POSTGRES_SHA }} &
docker pull mongo:7.0-jammy & docker pull mongo@${{ env.MONGODB_SHA }} &
docker pull mariadb:lts & docker pull mariadb@${{ env.MARIADB_SHA }} &
docker pull testcontainers/ryuk:0.5.1 &
docker pull budibase/couchdb:v3.2.1-sqs &
docker pull minio/minio & docker pull minio/minio &
docker pull redis & docker pull redis &
docker pull testcontainers/ryuk:0.5.1 &
docker pull budibase/couchdb:v3.3.3 &
wait $(jobs -p) wait $(jobs -p)

View File

@ -46,7 +46,7 @@ export default async function setup() {
await killContainers(containers) await killContainers(containers)
try { try {
const couchdb = new GenericContainer("budibase/couchdb:v3.2.1-sqs") const couchdb = new GenericContainer("budibase/couchdb:v3.3.3")
.withExposedPorts(5984, 4984) .withExposedPorts(5984, 4984)
.withEnvironment({ .withEnvironment({
COUCHDB_PASSWORD: "budibase", COUCHDB_PASSWORD: "budibase",

View File

@ -0,0 +1,5 @@
MSSQL_SHA=sha256:c4369c38385eba011c10906dc8892425831275bb035d5ce69656da8e29de50d8
MYSQL_SHA=sha256:9de9d54fecee6253130e65154b930978b1fcc336bcc86dfd06e89b72a2588ebe
POSTGRES_SHA=sha256:bd0d8e485d1aca439d39e5ea99b931160bd28d862e74c786f7508e9d0053090e
MONGODB_SHA=sha256:afa36bca12295b5f9dae68a493c706113922bdab520e901bd5d6c9d7247a1d8d
MARIADB_SHA=sha256:e59ba8783bf7bc02a4779f103bb0d8751ac0e10f9471089709608377eded7aa8

View File

@ -28,11 +28,11 @@ const { basicTable } = setup.structures
const ISO_REGEX_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/ const ISO_REGEX_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/
describe.each([ describe.each([
["internal", undefined], // ["internal", undefined],
[DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)],
[DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], // [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)],
[DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], // [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)],
[DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], // [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)],
])("/tables (%s)", (_, dsProvider) => { ])("/tables (%s)", (_, dsProvider) => {
const isInternal: boolean = !dsProvider const isInternal: boolean = !dsProvider
let datasource: Datasource | undefined let datasource: Datasource | undefined

View File

@ -0,0 +1,17 @@
import dotenv from "dotenv"
import { join } from "path"
const path = join(__dirname, "..", "..", "..", "..", "datasource-sha.env")
dotenv.config({
path,
})
export function getImageSHAs() {
return {
mssql: `mcr.microsoft.com/mssql/server@${process.env.MSSQL_SHA}`,
mysql: `mysql@${process.env.MYSQL_SHA}`,
postgres: `postgres@${process.env.POSTGRES_SHA}`,
mongodb: `mongo@${process.env.MONGODB_SHA}`,
mariadb: `mariadb@${process.env.MARIADB_SHA}`,
}
}

View File

@ -1,3 +1,4 @@
import "./images"
import { Datasource, SourceName } from "@budibase/types" import { Datasource, SourceName } from "@budibase/types"
import * as postgres from "./postgres" import * as postgres from "./postgres"
import * as mongodb from "./mongodb" import * as mongodb from "./mongodb"
@ -67,7 +68,12 @@ export async function knexClient(ds: Datasource) {
export async function startContainer(container: GenericContainer) { export async function startContainer(container: GenericContainer) {
const imageName = (container as any).imageName.string as string const imageName = (container as any).imageName.string as string
const key = imageName.replaceAll("/", "-").replaceAll(":", "-") let key: string
if (imageName.includes("@sha256")) {
key = imageName.split("@")[0]
} else {
key = imageName.replaceAll("/", "-").replaceAll(":", "-")
}
container = container container = container
.withReuse() .withReuse()

View File

@ -4,6 +4,7 @@ import { AbstractWaitStrategy } from "testcontainers/build/wait-strategies/wait-
import { generator, testContainerUtils } from "@budibase/backend-core/tests" import { generator, testContainerUtils } from "@budibase/backend-core/tests"
import { startContainer } from "." import { startContainer } from "."
import { knexClient } from "./mysql" import { knexClient } from "./mysql"
import { getImageSHAs } from "./images"
let ports: Promise<testContainerUtils.Port[]> let ports: Promise<testContainerUtils.Port[]>
@ -27,7 +28,7 @@ class MariaDBWaitStrategy extends AbstractWaitStrategy {
export async function getDatasource(): Promise<Datasource> { export async function getDatasource(): Promise<Datasource> {
if (!ports) { if (!ports) {
ports = startContainer( ports = startContainer(
new GenericContainer("mariadb:lts") new GenericContainer(getImageSHAs().mariadb)
.withExposedPorts(3306) .withExposedPorts(3306)
.withEnvironment({ MARIADB_ROOT_PASSWORD: "password" }) .withEnvironment({ MARIADB_ROOT_PASSWORD: "password" })
.withWaitStrategy(new MariaDBWaitStrategy()) .withWaitStrategy(new MariaDBWaitStrategy())

View File

@ -2,13 +2,14 @@ import { generator, testContainerUtils } from "@budibase/backend-core/tests"
import { Datasource, SourceName } from "@budibase/types" import { Datasource, SourceName } from "@budibase/types"
import { GenericContainer, Wait } from "testcontainers" import { GenericContainer, Wait } from "testcontainers"
import { startContainer } from "." import { startContainer } from "."
import { getImageSHAs } from "./images"
let ports: Promise<testContainerUtils.Port[]> let ports: Promise<testContainerUtils.Port[]>
export async function getDatasource(): Promise<Datasource> { export async function getDatasource(): Promise<Datasource> {
if (!ports) { if (!ports) {
ports = startContainer( ports = startContainer(
new GenericContainer("mongo:7.0-jammy") new GenericContainer(getImageSHAs().mongodb)
.withExposedPorts(27017) .withExposedPorts(27017)
.withEnvironment({ .withEnvironment({
MONGO_INITDB_ROOT_USERNAME: "mongo", MONGO_INITDB_ROOT_USERNAME: "mongo",

View File

@ -3,15 +3,14 @@ import { GenericContainer, Wait } from "testcontainers"
import { generator, testContainerUtils } from "@budibase/backend-core/tests" import { generator, testContainerUtils } from "@budibase/backend-core/tests"
import { startContainer } from "." import { startContainer } from "."
import knex from "knex" import knex from "knex"
import { getImageSHAs } from "./images"
let ports: Promise<testContainerUtils.Port[]> let ports: Promise<testContainerUtils.Port[]>
export async function getDatasource(): Promise<Datasource> { export async function getDatasource(): Promise<Datasource> {
if (!ports) { if (!ports) {
ports = startContainer( ports = startContainer(
new GenericContainer( new GenericContainer(getImageSHAs().mssql)
"mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04"
)
.withExposedPorts(1433) .withExposedPorts(1433)
.withEnvironment({ .withEnvironment({
ACCEPT_EULA: "Y", ACCEPT_EULA: "Y",

View File

@ -4,6 +4,7 @@ import { AbstractWaitStrategy } from "testcontainers/build/wait-strategies/wait-
import { generator, testContainerUtils } from "@budibase/backend-core/tests" import { generator, testContainerUtils } from "@budibase/backend-core/tests"
import { startContainer } from "." import { startContainer } from "."
import knex from "knex" import knex from "knex"
import { getImageSHAs } from "./images"
let ports: Promise<testContainerUtils.Port[]> let ports: Promise<testContainerUtils.Port[]>
@ -30,7 +31,7 @@ class MySQLWaitStrategy extends AbstractWaitStrategy {
export async function getDatasource(): Promise<Datasource> { export async function getDatasource(): Promise<Datasource> {
if (!ports) { if (!ports) {
ports = startContainer( ports = startContainer(
new GenericContainer("mysql:8.3") new GenericContainer(getImageSHAs().mysql)
.withExposedPorts(3306) .withExposedPorts(3306)
.withEnvironment({ MYSQL_ROOT_PASSWORD: "password" }) .withEnvironment({ MYSQL_ROOT_PASSWORD: "password" })
.withWaitStrategy(new MySQLWaitStrategy().withStartupTimeout(10000)) .withWaitStrategy(new MySQLWaitStrategy().withStartupTimeout(10000))

View File

@ -3,13 +3,14 @@ import { GenericContainer, Wait } from "testcontainers"
import { generator, testContainerUtils } from "@budibase/backend-core/tests" import { generator, testContainerUtils } from "@budibase/backend-core/tests"
import { startContainer } from "." import { startContainer } from "."
import knex from "knex" import knex from "knex"
import { getImageSHAs } from "./images"
let ports: Promise<testContainerUtils.Port[]> let ports: Promise<testContainerUtils.Port[]>
export async function getDatasource(): Promise<Datasource> { export async function getDatasource(): Promise<Datasource> {
if (!ports) { if (!ports) {
ports = startContainer( ports = startContainer(
new GenericContainer("postgres:16.1-bullseye") new GenericContainer(getImageSHAs().postgres)
.withExposedPorts(5432) .withExposedPorts(5432)
.withEnvironment({ POSTGRES_PASSWORD: "password" }) .withEnvironment({ POSTGRES_PASSWORD: "password" })
.withWaitStrategy( .withWaitStrategy(