mirror of
https://github.com/graycoreio/github-actions-magento2.git
synced 2026-06-08 19:46:41 +00:00
feat(supported-version): add optional services output for each matrix entry (#206)
This commit is contained in:
@@ -22,6 +22,11 @@ inputs:
|
|||||||
default: "2y"
|
default: "2y"
|
||||||
description: "The time frame (from today). Only used in `recent` kind. String that defines a time duration using a combination of years (y), months (m), and days (d). Each unit is optional and can appear in any order, separated by spaces. For example `2y 2m 2d`. "
|
description: "The time frame (from today). Only used in `recent` kind. String that defines a time duration using a combination of years (y), months (m), and days (d). Each unit is optional and can appear in any order, separated by spaces. For example `2y 2m 2d`. "
|
||||||
|
|
||||||
|
include_services:
|
||||||
|
required: false
|
||||||
|
default: "false"
|
||||||
|
description: "Whether to include a `services` key in each matrix entry with GitHub Actions service configurations."
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
matrix:
|
matrix:
|
||||||
description: "The Github Actions matrix of software technologies required to run Magento."
|
description: "The Github Actions matrix of software technologies required to run Magento."
|
||||||
|
|||||||
Vendored
+32
-32
File diff suppressed because one or more lines are too long
@@ -2,21 +2,35 @@ import * as core from '@actions/core';
|
|||||||
import { validateKind } from './kind/validate-kinds';
|
import { validateKind } from './kind/validate-kinds';
|
||||||
import { getMatrixForKind } from './matrix/get-matrix-for-kind';
|
import { getMatrixForKind } from './matrix/get-matrix-for-kind';
|
||||||
import { validateProject } from "./project/validate-projects";
|
import { validateProject } from "./project/validate-projects";
|
||||||
|
import { buildServicesForEntry } from "./services/build-services";
|
||||||
|
|
||||||
|
|
||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const kind = core.getInput("kind");
|
const kind = core.getInput("kind");
|
||||||
const customVersions = core.getInput("custom_versions");
|
const customVersions = core.getInput("custom_versions");
|
||||||
const project = core.getInput("project");
|
const project = core.getInput("project");
|
||||||
const recent_time_frame = core.getInput("recent_time_frame");
|
const recent_time_frame = core.getInput("recent_time_frame");
|
||||||
|
const include_services = core.getInput("include_services") === "true";
|
||||||
|
|
||||||
validateProject(<any>project)
|
validateProject(<any>project)
|
||||||
|
|
||||||
validateKind(<any>kind, customVersions ? customVersions.split(',') : undefined);
|
validateKind(<any>kind, customVersions ? customVersions.split(',') : undefined);
|
||||||
|
|
||||||
core.setOutput('matrix', getMatrixForKind(kind, project, customVersions, recent_time_frame));
|
let matrix = getMatrixForKind(kind, project, customVersions, recent_time_frame);
|
||||||
}
|
|
||||||
|
if (include_services) {
|
||||||
|
matrix = {
|
||||||
|
magento: matrix.magento,
|
||||||
|
include: matrix.include.map((entry) => ({
|
||||||
|
...entry,
|
||||||
|
services: buildServicesForEntry(entry)
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
core.setOutput('matrix', matrix);
|
||||||
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
|
export interface ServiceConfig {
|
||||||
|
image: string;
|
||||||
|
env?: Record<string, string>;
|
||||||
|
ports?: string[];
|
||||||
|
options?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Services {
|
||||||
|
[serviceName: string]: ServiceConfig;
|
||||||
|
}
|
||||||
|
|
||||||
export interface PackageMatrixVersion {
|
export interface PackageMatrixVersion {
|
||||||
magento: string,
|
magento: string,
|
||||||
php: string | number,
|
php: string | number,
|
||||||
@@ -12,7 +23,8 @@ export interface PackageMatrixVersion {
|
|||||||
nginx: string,
|
nginx: string,
|
||||||
os: string,
|
os: string,
|
||||||
release: string,
|
release: string,
|
||||||
eol: string
|
eol: string,
|
||||||
|
services?: Services
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GithubActionsMatrix {
|
export interface GithubActionsMatrix {
|
||||||
|
|||||||
@@ -0,0 +1,248 @@
|
|||||||
|
import { buildServicesForEntry } from './build-services';
|
||||||
|
import { PackageMatrixVersion } from '../matrix/matrix-type';
|
||||||
|
|
||||||
|
const createTestEntry = (overrides: Partial<PackageMatrixVersion> = {}): PackageMatrixVersion => ({
|
||||||
|
magento: 'magento/project-community-edition:2.4.7',
|
||||||
|
php: '8.3',
|
||||||
|
composer: '2.7.4',
|
||||||
|
mysql: 'mysql:8.4',
|
||||||
|
elasticsearch: 'elasticsearch:8.11.4',
|
||||||
|
opensearch: 'opensearchproject/opensearch:2.19.1',
|
||||||
|
rabbitmq: 'rabbitmq:4.0-management',
|
||||||
|
redis: 'redis:7.2',
|
||||||
|
varnish: 'varnish:7.5',
|
||||||
|
valkey: 'valkey:8.0',
|
||||||
|
nginx: 'nginx:1.26',
|
||||||
|
os: 'ubuntu-latest',
|
||||||
|
release: '2024-04-09T00:00:00+0000',
|
||||||
|
eol: '2027-04-09T00:00:00+0000',
|
||||||
|
...overrides
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('buildServicesForEntry', () => {
|
||||||
|
describe('search engine selection', () => {
|
||||||
|
it('should prefer opensearch when both are available', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.opensearch).toBeDefined();
|
||||||
|
expect(services.opensearch.image).toBe('opensearchproject/opensearch:2.19.1');
|
||||||
|
expect(services.elasticsearch).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fall back to elasticsearch when opensearch is empty', () => {
|
||||||
|
const entry = createTestEntry({ opensearch: '' });
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.elasticsearch).toBeDefined();
|
||||||
|
expect(services.elasticsearch.image).toBe('elasticsearch:8.11.4');
|
||||||
|
expect(services.opensearch).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include search engine when neither is available', () => {
|
||||||
|
const entry = createTestEntry({ opensearch: '', elasticsearch: '' });
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.opensearch).toBeUndefined();
|
||||||
|
expect(services.elasticsearch).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('cache selection', () => {
|
||||||
|
it('should prefer valkey when both are available', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.valkey).toBeDefined();
|
||||||
|
expect(services.valkey.image).toBe('valkey:8.0');
|
||||||
|
expect(services.redis).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fall back to redis when valkey is empty', () => {
|
||||||
|
const entry = createTestEntry({ valkey: '' });
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.redis).toBeDefined();
|
||||||
|
expect(services.redis.image).toBe('redis:7.2');
|
||||||
|
expect(services.valkey).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include cache when neither is available', () => {
|
||||||
|
const entry = createTestEntry({ valkey: '', redis: '' });
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.valkey).toBeUndefined();
|
||||||
|
expect(services.redis).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('mysql configuration', () => {
|
||||||
|
it('should include mysql when available', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.mysql).toBeDefined();
|
||||||
|
expect(services.mysql.image).toBe('mysql:8.4');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include mysql when empty', () => {
|
||||||
|
const entry = createTestEntry({ mysql: '' });
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.mysql).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include correct mysql env configuration', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.mysql.env).toEqual({
|
||||||
|
MYSQL_DATABASE: 'magento_integration_tests',
|
||||||
|
MYSQL_USER: 'user',
|
||||||
|
MYSQL_PASSWORD: 'password',
|
||||||
|
MYSQL_ROOT_PASSWORD: 'rootpassword'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include correct mysql ports', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.mysql.ports).toEqual(['3306:3306']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include mysql health check options', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.mysql.options).toContain('--health-cmd');
|
||||||
|
expect(services.mysql.options).toContain('mysqladmin ping');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('rabbitmq configuration', () => {
|
||||||
|
it('should include rabbitmq when available', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.rabbitmq).toBeDefined();
|
||||||
|
expect(services.rabbitmq.image).toBe('rabbitmq:4.0-management');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include rabbitmq when empty', () => {
|
||||||
|
const entry = createTestEntry({ rabbitmq: '' });
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.rabbitmq).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include correct rabbitmq env configuration', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.rabbitmq.env).toEqual({
|
||||||
|
RABBITMQ_DEFAULT_USER: 'guest',
|
||||||
|
RABBITMQ_DEFAULT_PASS: 'guest'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include correct rabbitmq ports', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.rabbitmq.ports).toEqual(['5672:5672']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('opensearch configuration', () => {
|
||||||
|
it('should include correct opensearch env configuration', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.opensearch.env).toEqual({
|
||||||
|
'discovery.type': 'single-node',
|
||||||
|
'DISABLE_INSTALL_DEMO_CONFIG': 'true',
|
||||||
|
'DISABLE_SECURITY_PLUGIN': 'true'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include correct opensearch ports', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.opensearch.ports).toEqual(['9200:9200']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include opensearch health check options', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.opensearch.options).toContain('--health-cmd');
|
||||||
|
expect(services.opensearch.options).toContain('curl');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('elasticsearch configuration', () => {
|
||||||
|
it('should include correct elasticsearch env configuration', () => {
|
||||||
|
const entry = createTestEntry({ opensearch: '' });
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.elasticsearch.env).toEqual({
|
||||||
|
'discovery.type': 'single-node',
|
||||||
|
'xpack.security.enabled': 'false',
|
||||||
|
'xpack.security.http.ssl.enabled': 'false',
|
||||||
|
'xpack.security.transport.ssl.enabled': 'false'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include correct elasticsearch ports', () => {
|
||||||
|
const entry = createTestEntry({ opensearch: '' });
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.elasticsearch.ports).toEqual(['9200:9200']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('cache configuration', () => {
|
||||||
|
it('should include correct valkey ports', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.valkey.ports).toEqual(['6379:6379']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include correct redis ports', () => {
|
||||||
|
const entry = createTestEntry({ valkey: '' });
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(services.redis.ports).toEqual(['6379:6379']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('complete service output', () => {
|
||||||
|
it('should build all services when all are available', () => {
|
||||||
|
const entry = createTestEntry();
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(Object.keys(services)).toHaveLength(4);
|
||||||
|
expect(services.mysql).toBeDefined();
|
||||||
|
expect(services.opensearch).toBeDefined();
|
||||||
|
expect(services.rabbitmq).toBeDefined();
|
||||||
|
expect(services.valkey).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle entry with minimal services', () => {
|
||||||
|
const entry = createTestEntry({
|
||||||
|
mysql: '',
|
||||||
|
elasticsearch: '',
|
||||||
|
opensearch: '',
|
||||||
|
rabbitmq: '',
|
||||||
|
redis: '',
|
||||||
|
valkey: ''
|
||||||
|
});
|
||||||
|
const services = buildServicesForEntry(entry);
|
||||||
|
|
||||||
|
expect(Object.keys(services)).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
import { PackageMatrixVersion, Services } from '../matrix/matrix-type';
|
||||||
|
import {
|
||||||
|
mysqlConfig,
|
||||||
|
elasticsearchConfig,
|
||||||
|
opensearchConfig,
|
||||||
|
rabbitmqConfig,
|
||||||
|
redisConfig,
|
||||||
|
valkeyConfig
|
||||||
|
} from './service-config';
|
||||||
|
|
||||||
|
interface SearchEngineChoice {
|
||||||
|
type: 'opensearch' | 'elasticsearch';
|
||||||
|
image: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CacheChoice {
|
||||||
|
type: 'valkey' | 'redis';
|
||||||
|
image: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which search engine to use for a matrix entry.
|
||||||
|
* Prefers opensearch over elasticsearch.
|
||||||
|
*/
|
||||||
|
function getSearchEngineChoice(entry: PackageMatrixVersion): SearchEngineChoice | null {
|
||||||
|
if (entry.opensearch && entry.opensearch.trim() !== '') {
|
||||||
|
return { type: 'opensearch', image: entry.opensearch };
|
||||||
|
}
|
||||||
|
if (entry.elasticsearch && entry.elasticsearch.trim() !== '') {
|
||||||
|
return { type: 'elasticsearch', image: entry.elasticsearch };
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which cache to use for a matrix entry.
|
||||||
|
* Prefers valkey over redis.
|
||||||
|
*/
|
||||||
|
function getCacheChoice(entry: PackageMatrixVersion): CacheChoice | null {
|
||||||
|
if (entry.valkey && entry.valkey.trim() !== '') {
|
||||||
|
return { type: 'valkey', image: entry.valkey };
|
||||||
|
}
|
||||||
|
if (entry.redis && entry.redis.trim() !== '') {
|
||||||
|
return { type: 'redis', image: entry.redis };
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the services object for a single matrix entry.
|
||||||
|
*/
|
||||||
|
export function buildServicesForEntry(entry: PackageMatrixVersion): Services {
|
||||||
|
const services: Services = {};
|
||||||
|
|
||||||
|
// MySQL is always included if present
|
||||||
|
if (entry.mysql && entry.mysql.trim() !== '') {
|
||||||
|
services.mysql = mysqlConfig.getConfig(entry.mysql);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search engine: prefer opensearch over elasticsearch
|
||||||
|
const searchEngine = getSearchEngineChoice(entry);
|
||||||
|
if (searchEngine) {
|
||||||
|
if (searchEngine.type === 'opensearch') {
|
||||||
|
services.opensearch = opensearchConfig.getConfig(searchEngine.image);
|
||||||
|
} else {
|
||||||
|
services.elasticsearch = elasticsearchConfig.getConfig(searchEngine.image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RabbitMQ
|
||||||
|
if (entry.rabbitmq && entry.rabbitmq.trim() !== '') {
|
||||||
|
services.rabbitmq = rabbitmqConfig.getConfig(entry.rabbitmq);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache: prefer valkey over redis
|
||||||
|
const cache = getCacheChoice(entry);
|
||||||
|
if (cache) {
|
||||||
|
if (cache.type === 'valkey') {
|
||||||
|
services.valkey = valkeyConfig.getConfig(cache.image);
|
||||||
|
} else {
|
||||||
|
services.redis = redisConfig.getConfig(cache.image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import { ServiceConfig } from '../matrix/matrix-type';
|
||||||
|
|
||||||
|
export interface ServiceTemplate {
|
||||||
|
getConfig(image: string): ServiceConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mysqlConfig: ServiceTemplate = {
|
||||||
|
getConfig(image: string): ServiceConfig {
|
||||||
|
return {
|
||||||
|
image,
|
||||||
|
env: {
|
||||||
|
MYSQL_DATABASE: 'magento_integration_tests',
|
||||||
|
MYSQL_USER: 'user',
|
||||||
|
MYSQL_PASSWORD: 'password',
|
||||||
|
MYSQL_ROOT_PASSWORD: 'rootpassword'
|
||||||
|
},
|
||||||
|
ports: ['3306:3306'],
|
||||||
|
options: '--health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const elasticsearchConfig: ServiceTemplate = {
|
||||||
|
getConfig(image: string): ServiceConfig {
|
||||||
|
return {
|
||||||
|
image,
|
||||||
|
env: {
|
||||||
|
'discovery.type': 'single-node',
|
||||||
|
'xpack.security.enabled': 'false',
|
||||||
|
'xpack.security.http.ssl.enabled': 'false',
|
||||||
|
'xpack.security.transport.ssl.enabled': 'false'
|
||||||
|
},
|
||||||
|
ports: ['9200:9200'],
|
||||||
|
options: '--health-cmd "curl http://localhost:9200/_cluster/health" --health-interval 10s --health-timeout 5s --health-retries 10'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const opensearchConfig: ServiceTemplate = {
|
||||||
|
getConfig(image: string): ServiceConfig {
|
||||||
|
return {
|
||||||
|
image,
|
||||||
|
env: {
|
||||||
|
'discovery.type': 'single-node',
|
||||||
|
'DISABLE_INSTALL_DEMO_CONFIG': 'true',
|
||||||
|
'DISABLE_SECURITY_PLUGIN': 'true'
|
||||||
|
},
|
||||||
|
ports: ['9200:9200'],
|
||||||
|
options: '--health-cmd "curl http://localhost:9200/_cluster/health" --health-interval 10s --health-timeout 5s --health-retries 10'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const rabbitmqConfig: ServiceTemplate = {
|
||||||
|
getConfig(image: string): ServiceConfig {
|
||||||
|
return {
|
||||||
|
image,
|
||||||
|
env: {
|
||||||
|
RABBITMQ_DEFAULT_USER: 'guest',
|
||||||
|
RABBITMQ_DEFAULT_PASS: 'guest'
|
||||||
|
},
|
||||||
|
ports: ['5672:5672']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const redisConfig: ServiceTemplate = {
|
||||||
|
getConfig(image: string): ServiceConfig {
|
||||||
|
return {
|
||||||
|
image,
|
||||||
|
ports: ['6379:6379']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const valkeyConfig: ServiceTemplate = {
|
||||||
|
getConfig(image: string): ServiceConfig {
|
||||||
|
return {
|
||||||
|
image,
|
||||||
|
ports: ['6379:6379']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
"opensearch": "opensearchproject/opensearch:2.19.1",
|
"opensearch": "opensearchproject/opensearch:2.19.1",
|
||||||
"rabbitmq": "rabbitmq:4.0-management",
|
"rabbitmq": "rabbitmq:4.0-management",
|
||||||
"redis": "redis:7.2",
|
"redis": "redis:7.2",
|
||||||
"valkey": "valkey:8.0",
|
"valkey": "valkey/valkey:8.0",
|
||||||
"varnish": "varnish:7.6",
|
"varnish": "varnish:7.6",
|
||||||
"nginx": "nginx:1.26",
|
"nginx": "nginx:1.26",
|
||||||
"os": "ubuntu-latest",
|
"os": "ubuntu-latest",
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
"opensearch": "opensearchproject/opensearch:2.19.1",
|
"opensearch": "opensearchproject/opensearch:2.19.1",
|
||||||
"rabbitmq": "rabbitmq:4.0-management",
|
"rabbitmq": "rabbitmq:4.0-management",
|
||||||
"redis": "redis:7.2",
|
"redis": "redis:7.2",
|
||||||
"valkey": "valkey:8.0",
|
"valkey": "valkey/valkey:8.0",
|
||||||
"varnish": "varnish:7.6",
|
"varnish": "varnish:7.6",
|
||||||
"nginx": "nginx:1.26",
|
"nginx": "nginx:1.26",
|
||||||
"os": "ubuntu-latest",
|
"os": "ubuntu-latest",
|
||||||
@@ -163,7 +163,7 @@
|
|||||||
"composer": "2.8.8",
|
"composer": "2.8.8",
|
||||||
"mysql": "mysql:8.4",
|
"mysql": "mysql:8.4",
|
||||||
"elasticsearch": "elasticsearch:8.17.4",
|
"elasticsearch": "elasticsearch:8.17.4",
|
||||||
"valkey": "valkey:8.0",
|
"valkey": "valkey/valkey:8.0",
|
||||||
"opensearch": "opensearchproject/opensearch:2.19.1",
|
"opensearch": "opensearchproject/opensearch:2.19.1",
|
||||||
"rabbitmq": "rabbitmq:4.0-management",
|
"rabbitmq": "rabbitmq:4.0-management",
|
||||||
"redis": "redis:7.2",
|
"redis": "redis:7.2",
|
||||||
|
|||||||
@@ -806,7 +806,7 @@
|
|||||||
"opensearch": "opensearchproject/opensearch:2.19.1",
|
"opensearch": "opensearchproject/opensearch:2.19.1",
|
||||||
"rabbitmq": "rabbitmq:4.0-management",
|
"rabbitmq": "rabbitmq:4.0-management",
|
||||||
"redis": "redis:7.2",
|
"redis": "redis:7.2",
|
||||||
"valkey": "valkey:8.0",
|
"valkey": "valkey/valkey:8.0",
|
||||||
"varnish": "varnish:7.6",
|
"varnish": "varnish:7.6",
|
||||||
"nginx": "nginx:1.26",
|
"nginx": "nginx:1.26",
|
||||||
"os": "ubuntu-latest",
|
"os": "ubuntu-latest",
|
||||||
|
|||||||
Reference in New Issue
Block a user