Skip to content

Commit 6fe9e8c

Browse files
committed
Add fastapi deploy files
1 parent 1d194d1 commit 6fe9e8c

8 files changed

+237
-0
lines changed

src/github_actions.rs

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,6 +1897,99 @@ jobs:
18971897
)
18981898
}
18991899

1900+
#[cfg(feature = "fastapi")]
1901+
fn create_testing_deploy_file() -> String {
1902+
r#"name: Deploy to Testing
1903+
on:
1904+
push:
1905+
branches:
1906+
- main
1907+
workflow_dispatch:
1908+
jobs:
1909+
deploy:
1910+
runs-on:
1911+
- self-hosted
1912+
- testing
1913+
env:
1914+
ENVIRONMENT: testing
1915+
DOMAIN: ${{ secrets.DOMAIN_TESTING }}
1916+
STACK_NAME: ${{ secrets.STACK_NAME_TESTING }}
1917+
SECRET_KEY: ${{ secrets.SECRET_KEY }}
1918+
FIRST_SUPERUSER_EMAIL: ${{ secrets.FIRST_SUPERUSER_EMAIL }}
1919+
FIRST_SUPERUSER_PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}
1920+
FIRST_SUPERUSER_NAME: ${{ secrets.FIRST_SUPERUSER_NAME }}
1921+
POSTGRES_HOST: ${{ secrets.POSTGRES_HOST }}
1922+
POSTGRES_USER: ${{ secrets.POSTGRES_USER }}
1923+
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
1924+
POSTGRES_DB: ${{ secrets.POSTGRES_DB }}
1925+
VALKEY_HOST: ${{ secrets.VALKEY_HOST }}
1926+
VALKEY_PASSWORD: ${{ secrets.VALKEY_PASSWORD }}
1927+
HANDWRITING_OCR_TOKEN: ${{ secrets.HANDWRITING_OCR_TOKEN }}
1928+
USERNAME: ${{ secrets.FIRST_SUPERUSER_EMAIL }}
1929+
PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}
1930+
EMAIL: ${{ secrets.FIRST_SUPERUSER_EMAIL }}
1931+
ERROR_NOTIFICATION_URL: ${{ secrets.ERROR_NOTIFICATION_URL_TESTING }}
1932+
LOG_LEVEL: "DEBUG"
1933+
steps:
1934+
- name: Fix permissions
1935+
run: |
1936+
if [ -d "./data" ]; then
1937+
sudo chown -R $USER:$USER ./data
1938+
fi
1939+
- name: Checkout
1940+
uses: actions/checkout@v5
1941+
- name: Create .env file
1942+
run: |
1943+
HASHED_PASSWORD=$(openssl passwd -apr1 "${PASSWORD}" | sed 's/\$/\$\$/g')
1944+
cat > .env << EOF
1945+
ENVIRONMENT=${ENVIRONMENT}
1946+
DOMAIN=${DOMAIN}
1947+
STACK_NAME=${STACK_NAME}
1948+
SECRET_KEY=${SECRET_KEY}
1949+
FIRST_SUPERUSER_EMAIL=${FIRST_SUPERUSER_EMAIL}
1950+
FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD}
1951+
FIRST_SUPERUSER_NAME=${FIRST_SUPERUSER_NAME}
1952+
POSTGRES_HOST=${POSTGRES_HOST}
1953+
POSTGRES_USER=${POSTGRES_USER}
1954+
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
1955+
POSTGRES_DB=${POSTGRES_DB}
1956+
VALKEY_HOST=${VALKEY_HOST}
1957+
VALKEY_PASSWORD=${VALKEY_PASSWORD}
1958+
HANDWRITING_OCR_TOKEN=${HANDWRITING_OCR_TOKEN}
1959+
USERNAME=${FIRST_SUPERUSER_EMAIL}
1960+
PASSWORD=${FIRST_SUPERUSER_PASSWORD}
1961+
HASHED_PASSWORD=${HASHED_PASSWORD}
1962+
EMAIL=${FIRST_SUPERUSER_EMAIL}
1963+
ERROR_NOTIFICATION_URL=${ERROR_NOTIFICATION_URL}
1964+
LOG_LEVEL=${LOG_LEVEL}
1965+
EOF
1966+
- name: Build and restart containers
1967+
timeout-minutes: 15
1968+
run: |
1969+
docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_TESTING }} build
1970+
docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_TESTING }} up -d
1971+
"#.to_string()
1972+
}
1973+
1974+
#[cfg(feature = "fastapi")]
1975+
pub fn save_deploy_files(project_info: &ProjectInfo) -> Result<()> {
1976+
let testing_file_path = project_info
1977+
.base_dir()
1978+
.join(".github/workflows/deploy_testing.yml");
1979+
let testing_content = create_testing_deploy_file();
1980+
1981+
save_file_with_content(&testing_file_path, &testing_content)?;
1982+
1983+
let production_file_path = project_info
1984+
.base_dir()
1985+
.join(".github/workflows/deploy_production.yml");
1986+
let production_content = create_testing_deploy_file();
1987+
1988+
save_file_with_content(&production_file_path, &production_content)?;
1989+
1990+
Ok(())
1991+
}
1992+
19001993
pub fn save_pypi_publish_file(project_info: &ProjectInfo) -> Result<()> {
19011994
let file_path = project_info
19021995
.base_dir()
@@ -2131,6 +2224,9 @@ mod tests {
21312224
use std::fs::create_dir_all;
21322225
use tmp_path::tmp_path;
21332226

2227+
#[cfg(feature = "fastapi")]
2228+
use crate::project_info::DatabaseManager;
2229+
21342230
#[tmp_path]
21352231
fn project_info_dummy() -> ProjectInfo {
21362232
ProjectInfo {
@@ -2216,6 +2312,25 @@ mod tests {
22162312
assert_yaml_snapshot!(content);
22172313
}
22182314

2315+
#[cfg(feature = "fastapi")]
2316+
#[test]
2317+
fn test_save_poetry_ci_testing_fastapi_file() {
2318+
let mut project_info = project_info_dummy();
2319+
project_info.project_manager = ProjectManager::Poetry;
2320+
project_info.is_fastapi_project = true;
2321+
project_info.database_manager = Some(DatabaseManager::AsyncPg);
2322+
let base = project_info.base_dir();
2323+
create_dir_all(base.join(".github/workflows")).unwrap();
2324+
let expected_file = base.join(".github/workflows/testing.yml");
2325+
save_ci_testing_linux_only_file(&project_info).unwrap();
2326+
2327+
assert!(expected_file.is_file());
2328+
2329+
let content = std::fs::read_to_string(expected_file).unwrap();
2330+
2331+
assert_yaml_snapshot!(content);
2332+
}
2333+
22192334
#[test]
22202335
fn test_save_ci_testing_linux_only_file_pyo3() {
22212336
let mut project_info = project_info_dummy();
@@ -2232,6 +2347,25 @@ mod tests {
22322347
assert_yaml_snapshot!(content);
22332348
}
22342349

2350+
#[cfg(feature = "fastapi")]
2351+
#[test]
2352+
fn test_save_ci_testing_fastapi_file_pyo3() {
2353+
let mut project_info = project_info_dummy();
2354+
project_info.project_manager = ProjectManager::Maturin;
2355+
project_info.is_fastapi_project = true;
2356+
project_info.database_manager = Some(DatabaseManager::AsyncPg);
2357+
let base = project_info.base_dir();
2358+
create_dir_all(base.join(".github/workflows")).unwrap();
2359+
let expected_file = base.join(".github/workflows/testing.yml");
2360+
save_ci_testing_linux_only_file(&project_info).unwrap();
2361+
2362+
assert!(expected_file.is_file());
2363+
2364+
let content = std::fs::read_to_string(expected_file).unwrap();
2365+
2366+
assert_yaml_snapshot!(content);
2367+
}
2368+
22352369
#[test]
22362370
fn test_save_setuptools_ci_testing_linux_only_file() {
22372371
let mut project_info = project_info_dummy();
@@ -2249,6 +2383,25 @@ mod tests {
22492383
assert_yaml_snapshot!(content);
22502384
}
22512385

2386+
#[cfg(feature = "fastapi")]
2387+
#[test]
2388+
fn test_save_setuptools_ci_fastapi_file() {
2389+
let mut project_info = project_info_dummy();
2390+
project_info.project_manager = ProjectManager::Setuptools;
2391+
project_info.is_fastapi_project = true;
2392+
project_info.database_manager = Some(DatabaseManager::AsyncPg);
2393+
let base = project_info.base_dir();
2394+
create_dir_all(base.join(".github/workflows")).unwrap();
2395+
let expected_file = base.join(".github/workflows/testing.yml");
2396+
save_ci_testing_linux_only_file(&project_info).unwrap();
2397+
2398+
assert!(expected_file.is_file());
2399+
2400+
let content = std::fs::read_to_string(expected_file).unwrap();
2401+
2402+
assert_yaml_snapshot!(content);
2403+
}
2404+
22522405
#[test]
22532406
fn test_save_uv_ci_testing_linux_only_file() {
22542407
let mut project_info = project_info_dummy();
@@ -2266,6 +2419,25 @@ mod tests {
22662419
assert_yaml_snapshot!(content);
22672420
}
22682421

2422+
#[cfg(feature = "fastapi")]
2423+
#[test]
2424+
fn test_save_uv_ci_testing_fastapi_file() {
2425+
let mut project_info = project_info_dummy();
2426+
project_info.project_manager = ProjectManager::Uv;
2427+
project_info.is_fastapi_project = true;
2428+
project_info.database_manager = Some(DatabaseManager::AsyncPg);
2429+
let base = project_info.base_dir();
2430+
create_dir_all(base.join(".github/workflows")).unwrap();
2431+
let expected_file = base.join(".github/workflows/testing.yml");
2432+
save_ci_testing_linux_only_file(&project_info).unwrap();
2433+
2434+
assert!(expected_file.is_file());
2435+
2436+
let content = std::fs::read_to_string(expected_file).unwrap();
2437+
2438+
assert_yaml_snapshot!(content);
2439+
}
2440+
22692441
#[test]
22702442
fn test_save_pixi_ci_testing_linux_only_file() {
22712443
let mut project_info = project_info_dummy();
@@ -2715,6 +2887,28 @@ mod tests {
27152887
assert_yaml_snapshot!(content);
27162888
}
27172889

2890+
#[cfg(feature = "fastapi")]
2891+
#[test]
2892+
fn test_save_deploy_files() {
2893+
let mut project_info = project_info_dummy();
2894+
project_info.is_fastapi_project = true;
2895+
project_info.database_manager = Some(DatabaseManager::AsyncPg);
2896+
let base = project_info.base_dir();
2897+
create_dir_all(base.join(".github/workflows")).unwrap();
2898+
let expected_test_file = base.join(".github/workflows/deploy_testing.yml");
2899+
let expected_production_file = base.join(".github/workflows/deploy_production.yml");
2900+
save_deploy_files(&project_info).unwrap();
2901+
2902+
assert!(expected_test_file.is_file());
2903+
assert!(expected_production_file.is_file());
2904+
2905+
let test_content = std::fs::read_to_string(expected_test_file).unwrap();
2906+
let production_content = std::fs::read_to_string(expected_production_file).unwrap();
2907+
2908+
assert_yaml_snapshot!(test_content);
2909+
assert_yaml_snapshot!(production_content);
2910+
}
2911+
27182912
#[test]
27192913
fn test_save_docs_publish_file_pixi() {
27202914
let mut project_info = project_info_dummy();

src/project_generator.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ use crate::{
2020
utils::is_python_312_or_greater,
2121
};
2222

23+
#[cfg(feature = "fastapi")]
24+
use crate::github_actions::save_deploy_files;
25+
2326
fn create_directories(project_info: &ProjectInfo) -> Result<()> {
2427
let base = project_info.base_dir();
2528
let src = project_info.source_dir_path();
@@ -1538,6 +1541,16 @@ pub fn generate_project(project_info: &ProjectInfo) -> Result<()> {
15381541
_ => (),
15391542
}
15401543

1544+
#[cfg(feature = "fastapi")]
1545+
if project_info.use_continuous_deployment {
1546+
if project_info.is_fastapi_project && save_deploy_files(project_info).is_err() {
1547+
bail!("Error creating deploy files");
1548+
} else if save_pypi_publish_file(project_info).is_err() {
1549+
bail!("Error creating PyPI publish file");
1550+
}
1551+
}
1552+
1553+
#[cfg(not(feature = "fastapi"))]
15411554
if project_info.use_continuous_deployment && save_pypi_publish_file(project_info).is_err() {
15421555
bail!("Error creating PyPI publish file");
15431556
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: src/github_actions.rs
3+
expression: content
4+
---
5+
"name: Testing\n\non:\n push:\n branches:\n - main\n pull_request:\nenv:\n CARGO_TERM_COLOR: always\n RUST_BACKTRACE: 1\n RUSTFLAGS: \"-D warnings\"\n PYTHON_VERSION: \"3.9\"\n SECRET_KEY: \"someKey\"\n PRODUCTION_MODE: false\n FIRST_SUPERUSER_EMAIL: \"[email protected]\"\n FIRST_SUPERUSER_PASSWORD: \"somePassword1!\"\n FIRST_SUPERUSER_NAME: \"Super User\"\n POSTGRES_HOST: \"127.0.0.1\"\n POSTGRES_USER: \"postgres\"\n POSTGRES_PASSWORD: \"test_password\"\n POSTGRES_DB: \"test_db\"\n VALKEY_HOST: \"127.0.0.1\"\n VALKEY_PASSWORD: \"test_password\"\n MEILISEARCH_HOST: http://127.0.0.1\n STACK_NAME: \"test-stack\"\n DOMAIN: \"127.0.0.1\"\n LOG_LEVEL: \"DEBUG\"\n CI: true\njobs:\n clippy:\n name: Clippy\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v5\n - name: Install Rust\n uses: dtolnay/rust-toolchain@stable\n - name: Cache dependencies\n uses: Swatinem/rust-cache@v2\n - name: Run cargo clippy\n run: cargo clippy --all-targets -- --deny warnings\n fmt:\n name: Rustfmt\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v5\n - name: Install Rust\n uses: dtolnay/rust-toolchain@stable\n - name: Cache dependencies\n uses: Swatinem/rust-cache@v2\n - name: Run cargo fmt\n run: cargo fmt --all -- --check\n python-linting:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v5\n - name: Install uv\n uses: astral-sh/setup-uv@v6\n with:\n enable-cache: true\n - name: Set up Python\n uses: actions/setup-python@v6\n with:\n python-version: ${{ env.PYTHON_VERSION }}\n - name: Install Dependencies\n run: |\n uv sync --frozen\n uv run maturin build\n - name: Ruff format check\n run: uv run ruff format my_project tests --check\n - name: Lint with ruff\n run: uv run ruff check .\n - name: mypy check\n run: uv run mypy my_project tests\n testing:\n strategy:\n fail-fast: false\n matrix:\n python-version: [\"3.9\", \"3.10\", \"3.11\", \"3.12\"]\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v5\n - name: Install Rust\n uses: dtolnay/rust-toolchain@stable\n - name: Cache dependencies\n uses: Swatinem/rust-cache@v2\n - name: Install sqlx-cli\n run: cargo install sqlx-cli --no-default-features -F native-tls -F postgres\n - name: Install uv\n uses: astral-sh/setup-uv@v6\n with:\n enable-cache: true\n - name: Set up Python ${{ matrix.python-version }}\n uses: actions/setup-python@v6\n with:\n python-version: ${{ matrix.python-version }}\n - name: Install Dependencies\n run: |\n uv sync --frozen\n uv run maturin build\n - name: make .env\n run: touch .env\n - name: Start docker containers\n run: docker compose up db valkey migrations -d\n - name: Test with pytest\n run: uv run pytest -n auto\n"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: src/github_actions.rs
3+
expression: production_content
4+
---
5+
"name: Deploy to Testing\non:\n push:\n branches:\n - main\n workflow_dispatch:\njobs:\n deploy:\n runs-on:\n - self-hosted\n - testing\n env:\n ENVIRONMENT: testing\n DOMAIN: ${{ secrets.DOMAIN_TESTING }}\n STACK_NAME: ${{ secrets.STACK_NAME_TESTING }}\n SECRET_KEY: ${{ secrets.SECRET_KEY }}\n FIRST_SUPERUSER_EMAIL: ${{ secrets.FIRST_SUPERUSER_EMAIL }}\n FIRST_SUPERUSER_PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}\n FIRST_SUPERUSER_NAME: ${{ secrets.FIRST_SUPERUSER_NAME }}\n POSTGRES_HOST: ${{ secrets.POSTGRES_HOST }}\n POSTGRES_USER: ${{ secrets.POSTGRES_USER }}\n POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}\n POSTGRES_DB: ${{ secrets.POSTGRES_DB }}\n VALKEY_HOST: ${{ secrets.VALKEY_HOST }}\n VALKEY_PASSWORD: ${{ secrets.VALKEY_PASSWORD }}\n HANDWRITING_OCR_TOKEN: ${{ secrets.HANDWRITING_OCR_TOKEN }}\n USERNAME: ${{ secrets.FIRST_SUPERUSER_EMAIL }}\n PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}\n EMAIL: ${{ secrets.FIRST_SUPERUSER_EMAIL }}\n ERROR_NOTIFICATION_URL: ${{ secrets.ERROR_NOTIFICATION_URL_TESTING }}\n LOG_LEVEL: \"DEBUG\"\n steps:\n - name: Fix permissions\n run: |\n if [ -d \"./data\" ]; then\n sudo chown -R $USER:$USER ./data\n fi\n - name: Checkout\n uses: actions/checkout@v5\n - name: Create .env file\n run: |\n HASHED_PASSWORD=$(openssl passwd -apr1 \"${PASSWORD}\" | sed 's/\\$/\\$\\$/g')\n cat > .env << EOF\n ENVIRONMENT=${ENVIRONMENT}\n DOMAIN=${DOMAIN}\n STACK_NAME=${STACK_NAME}\n SECRET_KEY=${SECRET_KEY}\n FIRST_SUPERUSER_EMAIL=${FIRST_SUPERUSER_EMAIL}\n FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD}\n FIRST_SUPERUSER_NAME=${FIRST_SUPERUSER_NAME}\n POSTGRES_HOST=${POSTGRES_HOST}\n POSTGRES_USER=${POSTGRES_USER}\n POSTGRES_PASSWORD=${POSTGRES_PASSWORD}\n POSTGRES_DB=${POSTGRES_DB}\n VALKEY_HOST=${VALKEY_HOST}\n VALKEY_PASSWORD=${VALKEY_PASSWORD}\n HANDWRITING_OCR_TOKEN=${HANDWRITING_OCR_TOKEN}\n USERNAME=${FIRST_SUPERUSER_EMAIL}\n PASSWORD=${FIRST_SUPERUSER_PASSWORD}\n HASHED_PASSWORD=${HASHED_PASSWORD}\n EMAIL=${FIRST_SUPERUSER_EMAIL}\n ERROR_NOTIFICATION_URL=${ERROR_NOTIFICATION_URL}\n LOG_LEVEL=${LOG_LEVEL}\n EOF\n - name: Build and restart containers\n timeout-minutes: 15\n run: |\n docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_TESTING }} build\n docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_TESTING }} up -d\n"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: src/github_actions.rs
3+
expression: test_content
4+
---
5+
"name: Deploy to Testing\non:\n push:\n branches:\n - main\n workflow_dispatch:\njobs:\n deploy:\n runs-on:\n - self-hosted\n - testing\n env:\n ENVIRONMENT: testing\n DOMAIN: ${{ secrets.DOMAIN_TESTING }}\n STACK_NAME: ${{ secrets.STACK_NAME_TESTING }}\n SECRET_KEY: ${{ secrets.SECRET_KEY }}\n FIRST_SUPERUSER_EMAIL: ${{ secrets.FIRST_SUPERUSER_EMAIL }}\n FIRST_SUPERUSER_PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}\n FIRST_SUPERUSER_NAME: ${{ secrets.FIRST_SUPERUSER_NAME }}\n POSTGRES_HOST: ${{ secrets.POSTGRES_HOST }}\n POSTGRES_USER: ${{ secrets.POSTGRES_USER }}\n POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}\n POSTGRES_DB: ${{ secrets.POSTGRES_DB }}\n VALKEY_HOST: ${{ secrets.VALKEY_HOST }}\n VALKEY_PASSWORD: ${{ secrets.VALKEY_PASSWORD }}\n HANDWRITING_OCR_TOKEN: ${{ secrets.HANDWRITING_OCR_TOKEN }}\n USERNAME: ${{ secrets.FIRST_SUPERUSER_EMAIL }}\n PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}\n EMAIL: ${{ secrets.FIRST_SUPERUSER_EMAIL }}\n ERROR_NOTIFICATION_URL: ${{ secrets.ERROR_NOTIFICATION_URL_TESTING }}\n LOG_LEVEL: \"DEBUG\"\n steps:\n - name: Fix permissions\n run: |\n if [ -d \"./data\" ]; then\n sudo chown -R $USER:$USER ./data\n fi\n - name: Checkout\n uses: actions/checkout@v5\n - name: Create .env file\n run: |\n HASHED_PASSWORD=$(openssl passwd -apr1 \"${PASSWORD}\" | sed 's/\\$/\\$\\$/g')\n cat > .env << EOF\n ENVIRONMENT=${ENVIRONMENT}\n DOMAIN=${DOMAIN}\n STACK_NAME=${STACK_NAME}\n SECRET_KEY=${SECRET_KEY}\n FIRST_SUPERUSER_EMAIL=${FIRST_SUPERUSER_EMAIL}\n FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD}\n FIRST_SUPERUSER_NAME=${FIRST_SUPERUSER_NAME}\n POSTGRES_HOST=${POSTGRES_HOST}\n POSTGRES_USER=${POSTGRES_USER}\n POSTGRES_PASSWORD=${POSTGRES_PASSWORD}\n POSTGRES_DB=${POSTGRES_DB}\n VALKEY_HOST=${VALKEY_HOST}\n VALKEY_PASSWORD=${VALKEY_PASSWORD}\n HANDWRITING_OCR_TOKEN=${HANDWRITING_OCR_TOKEN}\n USERNAME=${FIRST_SUPERUSER_EMAIL}\n PASSWORD=${FIRST_SUPERUSER_PASSWORD}\n HASHED_PASSWORD=${HASHED_PASSWORD}\n EMAIL=${FIRST_SUPERUSER_EMAIL}\n ERROR_NOTIFICATION_URL=${ERROR_NOTIFICATION_URL}\n LOG_LEVEL=${LOG_LEVEL}\n EOF\n - name: Build and restart containers\n timeout-minutes: 15\n run: |\n docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_TESTING }} build\n docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_TESTING }} up -d\n"

0 commit comments

Comments
 (0)