5 Commits

Author SHA1 Message Date
copilotcoder
f037e7138d docs(dev): document Renovate manual dispatch behavior
All checks were successful
CICD / Build and Push CICD Images (push) Successful in 9m42s
CICD / Build CICD Image Failure Postmortem (push) Has been skipped
CICD / Source Checks (push) Successful in 2m19s
CICD / Source Lanes Failure Postmortem (push) Has been skipped
CICD / Build Release Images (push) Successful in 9m52s
CICD / Build Tester Images (push) Successful in 12m17s
CICD / Production Image Failures Postmortem (push) Has been skipped
CICD / Production Images Complete (push) Successful in 3s
CICD / Runtime Black-Box Integration Tests (push) Successful in 1m19s
CICD / Integration Tests Failure Postmortem (push) Has been skipped
CICD / End-to-End Tests (push) Successful in 2m12s
CICD / E2E Tests Failure Postmortem (push) Has been skipped
CICD / Promote Staging Images To Release (push) Successful in 42s
CICD / Dependency Audits (Informational) (push) Successful in 18m45s
CICD / CICD Tests Complete (push) Successful in 4s
2026-07-21 15:04:09 -04:00
copilotcoder
93b4000b20 ci(renovate): run manual dispatch outside schedule in single pass
Some checks failed
CICD / Build CICD Image Failure Postmortem (push) Has been cancelled
CICD / Source Checks (push) Has been cancelled
CICD / Dependency Audits (Informational) (push) Has been cancelled
CICD / CICD Tests Complete (push) Has been cancelled
CICD / Build Release Images (push) Has been cancelled
CICD / Build Tester Images (push) Has been cancelled
CICD / Production Images Complete (push) Has been cancelled
CICD / Production Image Failures Postmortem (push) Has been cancelled
CICD / Source Lanes Failure Postmortem (push) Has been cancelled
CICD / Runtime Black-Box Integration Tests (push) Has been cancelled
CICD / Integration Tests Failure Postmortem (push) Has been cancelled
CICD / End-to-End Tests (push) Has been cancelled
CICD / Build and Push CICD Images (push) Has been cancelled
CICD / E2E Tests Failure Postmortem (push) Has been cancelled
CICD / Promote Staging Images To Release (push) Has been cancelled
2026-07-21 14:24:45 -04:00
copilotcoder
996a018dad Working on debugging renovate, set log level back to debug.
Some checks failed
CICD / Build CICD Image Failure Postmortem (push) Has been cancelled
CICD / Source Checks (push) Has been cancelled
CICD / Dependency Audits (Informational) (push) Has been cancelled
CICD / Build and Push CICD Images (push) Has been cancelled
CICD / CICD Tests Complete (push) Has been cancelled
CICD / Build Release Images (push) Has been cancelled
CICD / Build Tester Images (push) Has been cancelled
CICD / Production Images Complete (push) Has been cancelled
CICD / Production Image Failures Postmortem (push) Has been cancelled
CICD / Source Lanes Failure Postmortem (push) Has been cancelled
CICD / Runtime Black-Box Integration Tests (push) Has been cancelled
CICD / Integration Tests Failure Postmortem (push) Has been cancelled
CICD / End-to-End Tests (push) Has been cancelled
CICD / E2E Tests Failure Postmortem (push) Has been cancelled
CICD / Promote Staging Images To Release (push) Has been cancelled
Signed-off-by: copilotcoder <copilotcoder@darkhelm.org>
2026-07-21 13:46:45 -04:00
copilotcoder
b1055ba605 Updating psycopg to 3.3.4
Some checks failed
CICD / Build and Push CICD Images (push) Successful in 12m11s
CICD / Build CICD Image Failure Postmortem (push) Has been skipped
CICD / Source Checks (push) Successful in 2m36s
CICD / Source Lanes Failure Postmortem (push) Has been skipped
CICD / Dependency Audits (Informational) (push) Successful in 1m28s
CICD / CICD Tests Complete (push) Successful in 8s
CICD / Build Tester Images (push) Successful in 6m31s
CICD / Build Release Images (push) Successful in 27m10s
CICD / Production Image Failures Postmortem (push) Has been skipped
CICD / Production Images Complete (push) Successful in 4s
CICD / End-to-End Tests (push) Successful in 6m38s
CICD / E2E Tests Failure Postmortem (push) Has been skipped
CICD / Runtime Black-Box Integration Tests (push) Successful in 21m37s
CICD / Integration Tests Failure Postmortem (push) Has been skipped
CICD / Promote Staging Images To Release (push) Successful in 44s
Renovate Dependency Updates / Renovate Dependencies (push) Failing after 12m58s
Signed-off-by: copilotcoder <copilotcoder@darkhelm.org>
2026-07-20 20:50:10 -04:00
copilotcoder
5efe0446d5 Rename runtime images to explicit plex-playlist names
Some checks failed
CICD / Build CICD Image Failure Postmortem (push) Has been cancelled
CICD / Source Checks (push) Has been cancelled
CICD / Dependency Audits (Informational) (push) Has been cancelled
CICD / CICD Tests Complete (push) Has been cancelled
CICD / Build Release Images (push) Has been cancelled
CICD / Build Tester Images (push) Has been cancelled
CICD / Production Images Complete (push) Has been cancelled
CICD / Production Image Failures Postmortem (push) Has been cancelled
CICD / Build and Push CICD Images (push) Has been cancelled
CICD / Source Lanes Failure Postmortem (push) Has been cancelled
CICD / Runtime Black-Box Integration Tests (push) Has been cancelled
CICD / Integration Tests Failure Postmortem (push) Has been cancelled
CICD / End-to-End Tests (push) Has been cancelled
CICD / E2E Tests Failure Postmortem (push) Has been cancelled
CICD / Promote Staging Images To Release (push) Has been cancelled
2026-07-20 20:44:58 -04:00
11 changed files with 718 additions and 704 deletions

View File

@@ -1173,7 +1173,7 @@ jobs:
return 1 return 1
} }
DEPLOYABLE_BACKEND_REPO="${GITEA_REGISTRY}/darkhelm.org/deployable-backend-staging" DEPLOYABLE_BACKEND_REPO="${GITEA_REGISTRY}/darkhelm.org/plex-playlist-backend-staging"
DEPLOYABLE_BACKEND_TAG_REF="${DEPLOYABLE_BACKEND_REPO}:${HEAD_SHA}" DEPLOYABLE_BACKEND_TAG_REF="${DEPLOYABLE_BACKEND_REPO}:${HEAD_SHA}"
DEPLOYABLE_BACKEND_CACHE_REF="${DEPLOYABLE_BACKEND_REPO}:cache" DEPLOYABLE_BACKEND_CACHE_REF="${DEPLOYABLE_BACKEND_REPO}:cache"
@@ -1182,11 +1182,11 @@ jobs:
DOCKER_BUILDKIT=1 docker build -f Dockerfile.backend \ DOCKER_BUILDKIT=1 docker build -f Dockerfile.backend \
--cache-from "${DEPLOYABLE_BACKEND_CACHE_REF}" \ --cache-from "${DEPLOYABLE_BACKEND_CACHE_REF}" \
--build-arg BUILDKIT_INLINE_CACHE=1 \ --build-arg BUILDKIT_INLINE_CACHE=1 \
-t deployable-backend:"${HEAD_SHA}" . -t plex-playlist-backend:"${HEAD_SHA}" .
bash ./scripts/verify-deployable-image-purity.sh --image deployable-backend:"${HEAD_SHA}" --profile backend bash ./scripts/verify-deployable-image-purity.sh --image plex-playlist-backend:"${HEAD_SHA}" --profile backend
docker tag "deployable-backend:${HEAD_SHA}" "${DEPLOYABLE_BACKEND_TAG_REF}" docker tag "plex-playlist-backend:${HEAD_SHA}" "${DEPLOYABLE_BACKEND_TAG_REF}"
docker tag "deployable-backend:${HEAD_SHA}" "${DEPLOYABLE_BACKEND_CACHE_REF}" docker tag "plex-playlist-backend:${HEAD_SHA}" "${DEPLOYABLE_BACKEND_CACHE_REF}"
retry_registry_op push "${DEPLOYABLE_BACKEND_TAG_REF}" 5 4 retry_registry_op push "${DEPLOYABLE_BACKEND_TAG_REF}" 5 4
retry_registry_op push "${DEPLOYABLE_BACKEND_CACHE_REF}" 5 4 retry_registry_op push "${DEPLOYABLE_BACKEND_CACHE_REF}" 5 4
@@ -1281,7 +1281,7 @@ jobs:
return 1 return 1
} }
DEPLOYABLE_FRONTEND_REPO="${GITEA_REGISTRY}/darkhelm.org/deployable-frontend-staging" DEPLOYABLE_FRONTEND_REPO="${GITEA_REGISTRY}/darkhelm.org/plex-playlist-frontend-staging"
DEPLOYABLE_FRONTEND_TAG_REF="${DEPLOYABLE_FRONTEND_REPO}:${HEAD_SHA}" DEPLOYABLE_FRONTEND_TAG_REF="${DEPLOYABLE_FRONTEND_REPO}:${HEAD_SHA}"
DEPLOYABLE_FRONTEND_CACHE_REF="${DEPLOYABLE_FRONTEND_REPO}:cache" DEPLOYABLE_FRONTEND_CACHE_REF="${DEPLOYABLE_FRONTEND_REPO}:cache"
@@ -1291,11 +1291,11 @@ jobs:
--target production \ --target production \
--cache-from "${DEPLOYABLE_FRONTEND_CACHE_REF}" \ --cache-from "${DEPLOYABLE_FRONTEND_CACHE_REF}" \
--build-arg BUILDKIT_INLINE_CACHE=1 \ --build-arg BUILDKIT_INLINE_CACHE=1 \
-t deployable-frontend:"${HEAD_SHA}" . -t plex-playlist-frontend:"${HEAD_SHA}" .
bash ./scripts/verify-deployable-image-purity.sh --image deployable-frontend:"${HEAD_SHA}" --profile frontend bash ./scripts/verify-deployable-image-purity.sh --image plex-playlist-frontend:"${HEAD_SHA}" --profile frontend
docker tag "deployable-frontend:${HEAD_SHA}" "${DEPLOYABLE_FRONTEND_TAG_REF}" docker tag "plex-playlist-frontend:${HEAD_SHA}" "${DEPLOYABLE_FRONTEND_TAG_REF}"
docker tag "deployable-frontend:${HEAD_SHA}" "${DEPLOYABLE_FRONTEND_CACHE_REF}" docker tag "plex-playlist-frontend:${HEAD_SHA}" "${DEPLOYABLE_FRONTEND_CACHE_REF}"
retry_registry_op push "${DEPLOYABLE_FRONTEND_TAG_REF}" 5 4 retry_registry_op push "${DEPLOYABLE_FRONTEND_TAG_REF}" 5 4
retry_registry_op push "${DEPLOYABLE_FRONTEND_CACHE_REF}" 5 4 retry_registry_op push "${DEPLOYABLE_FRONTEND_CACHE_REF}" 5 4
@@ -2617,12 +2617,12 @@ jobs:
if [ -z "${STAGING_BACKEND_DIGEST_REF}" ]; then if [ -z "${STAGING_BACKEND_DIGEST_REF}" ]; then
echo "Staging backend digest output missing; deriving from staging tag ${HEAD_SHA}" echo "Staging backend digest output missing; deriving from staging tag ${HEAD_SHA}"
STAGING_BACKEND_DIGEST_REF="$(resolve_staging_digest_from_tag "${GITEA_REGISTRY}/darkhelm.org/deployable-backend-staging" "${HEAD_SHA}")" STAGING_BACKEND_DIGEST_REF="$(resolve_staging_digest_from_tag "${GITEA_REGISTRY}/darkhelm.org/plex-playlist-backend-staging" "${HEAD_SHA}")"
fi fi
if [ -z "${STAGING_FRONTEND_DIGEST_REF}" ]; then if [ -z "${STAGING_FRONTEND_DIGEST_REF}" ]; then
echo "Staging frontend digest output missing; deriving from staging tag ${HEAD_SHA}" echo "Staging frontend digest output missing; deriving from staging tag ${HEAD_SHA}"
STAGING_FRONTEND_DIGEST_REF="$(resolve_staging_digest_from_tag "${GITEA_REGISTRY}/darkhelm.org/deployable-frontend-staging" "${HEAD_SHA}")" STAGING_FRONTEND_DIGEST_REF="$(resolve_staging_digest_from_tag "${GITEA_REGISTRY}/darkhelm.org/plex-playlist-frontend-staging" "${HEAD_SHA}")"
fi fi
if [ -z "${STAGING_BACKEND_DIGEST_REF}" ] || [ -z "${STAGING_FRONTEND_DIGEST_REF}" ]; then if [ -z "${STAGING_BACKEND_DIGEST_REF}" ] || [ -z "${STAGING_FRONTEND_DIGEST_REF}" ]; then
@@ -2683,8 +2683,8 @@ jobs:
PREVIOUS_RELEASE_VERSION="$(printf '%s\n' "${RELEASE_TAG_LIST}" | awk -v current="${RELEASE_VERSION}" 'NF {if ($0 == current) {print prev; found=1; exit} prev=$0} END {if (!found) print prev}')" PREVIOUS_RELEASE_VERSION="$(printf '%s\n' "${RELEASE_TAG_LIST}" | awk -v current="${RELEASE_VERSION}" 'NF {if ($0 == current) {print prev; found=1; exit} prev=$0} END {if (!found) print prev}')"
RELEASE_BACKEND_REPO="${GITEA_REGISTRY}/darkhelm.org/deployable-backend" RELEASE_BACKEND_REPO="${GITEA_REGISTRY}/darkhelm.org/plex-playlist-backend"
RELEASE_FRONTEND_REPO="${GITEA_REGISTRY}/darkhelm.org/deployable-frontend" RELEASE_FRONTEND_REPO="${GITEA_REGISTRY}/darkhelm.org/plex-playlist-frontend"
BACKEND_RELEASE_VERSION_REF="${RELEASE_BACKEND_REPO}:${RELEASE_VERSION}" BACKEND_RELEASE_VERSION_REF="${RELEASE_BACKEND_REPO}:${RELEASE_VERSION}"
BACKEND_RELEASE_TAGGED_REF="${RELEASE_BACKEND_REPO}:${RELEASE_TAGGED_VERSION}" BACKEND_RELEASE_TAGGED_REF="${RELEASE_BACKEND_REPO}:${RELEASE_TAGGED_VERSION}"

View File

@@ -180,7 +180,7 @@ jobs:
RENOVATE_NODE_ARGS: --max-old-space-size=768 RENOVATE_NODE_ARGS: --max-old-space-size=768
RENOVATE_OSV_VULNERABILITY_ALERTS: "false" RENOVATE_OSV_VULNERABILITY_ALERTS: "false"
RENOVATE_FETCH_CHANGELOGS: "off" RENOVATE_FETCH_CHANGELOGS: "off"
LOG_LEVEL: info LOG_LEVEL: debug
run: | run: |
set -euo pipefail set -euo pipefail
@@ -401,9 +401,11 @@ jobs:
# Manual workflow dispatch should execute immediately, regardless of repository schedule windows. # Manual workflow dispatch should execute immediately, regardless of repository schedule windows.
if [ "${GITHUB_EVENT_NAME:-}" = "workflow_dispatch" ]; then if [ "${GITHUB_EVENT_NAME:-}" = "workflow_dispatch" ]; then
export RENOVATE_IGNORE_SCHEDULE="true" export RENOVATE_IGNORE_SCHEDULE="true"
echo "✓ Manual run detected: ignoring Renovate schedule constraints" export RENOVATE_SCHEDULE="at any time"
echo "✓ Manual run detected: forcing Renovate outside schedule windows"
else else
unset RENOVATE_IGNORE_SCHEDULE unset RENOVATE_IGNORE_SCHEDULE
unset RENOVATE_SCHEDULE
fi fi
# Multi-batch runs must not prune branches created by earlier batches. # Multi-batch runs must not prune branches created by earlier batches.
@@ -412,22 +414,16 @@ jobs:
run_renovate_with_endpoint() { run_renovate_with_endpoint() {
endpoint="$1" endpoint="$1"
enabled_managers="$2" enabled_managers="$2"
batch_label="$3"
batch_node_args="${RENOVATE_NODE_ARGS}"
batch_pr_limit="${RENOVATE_PR_CONCURRENT_LIMIT}"
batch_branch_limit="${RENOVATE_BRANCH_CONCURRENT_LIMIT}"
if [ "${batch_label}" = "npm" ]; then single_pass_node_args="${RENOVATE_NODE_ARGS}"
batch_node_args="--max-old-space-size=1536" single_pass_pr_limit="${RENOVATE_PR_CONCURRENT_LIMIT}"
batch_pr_limit="1" single_pass_branch_limit="${RENOVATE_BRANCH_CONCURRENT_LIMIT}"
batch_branch_limit="1"
fi
export RENOVATE_ENDPOINT="${endpoint}" export RENOVATE_ENDPOINT="${endpoint}"
echo "Running Renovate batch '${batch_label}' with endpoint: ${RENOVATE_ENDPOINT}" echo "Running Renovate single pass with endpoint: ${RENOVATE_ENDPOINT}"
echo "Enabled managers for '${batch_label}': ${enabled_managers}" echo "Enabled managers: ${enabled_managers}"
echo "Node args for '${batch_label}': ${batch_node_args}" echo "Node args: ${single_pass_node_args}"
echo "PR/branch limits for '${batch_label}': ${batch_pr_limit}/${batch_branch_limit}" echo "PR/branch limits: ${single_pass_pr_limit}/${single_pass_branch_limit}"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
docker run --rm ${DOCKER_ADD_HOST_ARG} \ docker run --rm ${DOCKER_ADD_HOST_ARG} \
@@ -448,12 +444,13 @@ jobs:
-e RENOVATE_GIT_AUTHOR \ -e RENOVATE_GIT_AUTHOR \
-e RENOVATE_ONBOARDING \ -e RENOVATE_ONBOARDING \
-e RENOVATE_REQUIRE_CONFIG \ -e RENOVATE_REQUIRE_CONFIG \
-e RENOVATE_PR_CONCURRENT_LIMIT="${batch_pr_limit}" \ -e RENOVATE_PR_CONCURRENT_LIMIT="${single_pass_pr_limit}" \
-e RENOVATE_BRANCH_CONCURRENT_LIMIT="${batch_branch_limit}" \ -e RENOVATE_BRANCH_CONCURRENT_LIMIT="${single_pass_branch_limit}" \
-e RENOVATE_NODE_ARGS="${batch_node_args}" \ -e RENOVATE_NODE_ARGS="${single_pass_node_args}" \
-e RENOVATE_OSV_VULNERABILITY_ALERTS \ -e RENOVATE_OSV_VULNERABILITY_ALERTS \
-e RENOVATE_FETCH_CHANGELOGS \ -e RENOVATE_FETCH_CHANGELOGS \
-e RENOVATE_IGNORE_SCHEDULE \ -e RENOVATE_IGNORE_SCHEDULE \
-e RENOVATE_SCHEDULE \
-e RENOVATE_PRUNE_STALE_BRANCHES \ -e RENOVATE_PRUNE_STALE_BRANCHES \
-e RENOVATE_ENABLED_MANAGERS="${enabled_managers}" \ -e RENOVATE_ENABLED_MANAGERS="${enabled_managers}" \
--entrypoint /bin/sh \ --entrypoint /bin/sh \
@@ -469,30 +466,27 @@ jobs:
renovate --platform "${RENOVATE_PLATFORM}" --endpoint "${RENOVATE_ENDPOINT}" --git-url "${RENOVATE_GIT_URL}" --git-author "${RENOVATE_GIT_AUTHOR}" --onboarding="${RENOVATE_ONBOARDING}" --pr-concurrent-limit "${RENOVATE_PR_CONCURRENT_LIMIT}" --branch-concurrent-limit "${RENOVATE_BRANCH_CONCURRENT_LIMIT}" --osv-vulnerability-alerts="${RENOVATE_OSV_VULNERABILITY_ALERTS}" --enabled-managers "${RENOVATE_ENABLED_MANAGERS}" DarkHelm.org/plex-playlist' renovate --platform "${RENOVATE_PLATFORM}" --endpoint "${RENOVATE_ENDPOINT}" --git-url "${RENOVATE_GIT_URL}" --git-author "${RENOVATE_GIT_AUTHOR}" --onboarding="${RENOVATE_ONBOARDING}" --pr-concurrent-limit "${RENOVATE_PR_CONCURRENT_LIMIT}" --branch-concurrent-limit "${RENOVATE_BRANCH_CONCURRENT_LIMIT}" --osv-vulnerability-alerts="${RENOVATE_OSV_VULNERABILITY_ALERTS}" --enabled-managers "${RENOVATE_ENABLED_MANAGERS}" DarkHelm.org/plex-playlist'
} }
run_batch_with_fallback() { run_single_pass_with_fallback() {
enabled_managers="$1" enabled_managers="$1"
batch_label="$2"
if run_renovate_with_endpoint "${BASE_ENDPOINT}" "${enabled_managers}" "${batch_label}" 2>&1 | tee -a /tmp/renovate.log; then if run_renovate_with_endpoint "${BASE_ENDPOINT}" "${enabled_managers}" 2>&1 | tee -a /tmp/renovate.log; then
return 0 return 0
fi fi
primary_status=$? primary_status=$?
if [ "${primary_status}" -eq 137 ] || tail -n 400 /tmp/renovate.log | grep -qE '(^|[[:space:]])Killed($|[[:space:]])|exitcode '\''137'\''' ; then if [ "${primary_status}" -eq 137 ] || tail -n 400 /tmp/renovate.log | grep -qE '(^|[[:space:]])Killed($|[[:space:]])|exitcode '\''137'\''' ; then
echo "❌ Renovate batch '${batch_label}' terminated by OOM/kill signal on primary endpoint; skipping endpoint retry" echo "❌ Renovate single pass terminated by OOM/kill signal on primary endpoint; skipping endpoint retry"
return "${primary_status}" return "${primary_status}"
fi fi
echo "⚠ Renovate batch '${batch_label}' failed with primary endpoint. Retrying with API endpoint form..." echo "⚠ Renovate single pass failed with primary endpoint. Retrying with API endpoint form..."
run_renovate_with_endpoint "${API_ENDPOINT}" "${enabled_managers}" "${batch_label}" 2>&1 | tee -a /tmp/renovate.log run_renovate_with_endpoint "${API_ENDPOINT}" "${enabled_managers}" 2>&1 | tee -a /tmp/renovate.log
} }
: > /tmp/renovate.log : > /tmp/renovate.log
# Run low-memory batches sequentially to keep peak usage below constrained runner limits. # Run Renovate once across all enabled managers.
run_batch_with_fallback "docker-compose,dockerfile" "containers" run_single_pass_with_fallback "docker-compose,dockerfile,github-actions,npm,pep621"
run_batch_with_fallback "github-actions,pep621" "python-and-actions"
run_batch_with_fallback "npm" "npm"
echo "✓ Renovate execution completed" echo "✓ Renovate execution completed"

View File

@@ -37,7 +37,7 @@ classifiers = [
dependencies = [ dependencies = [
"fastapi==0.139.0", "fastapi==0.139.0",
"sqlalchemy==2.0.51", "sqlalchemy==2.0.51",
"psycopg[binary]==3.2.12", "psycopg[binary]==3.3.4",
"uvicorn==0.51.0" "uvicorn==0.51.0"
] ]
description = "Backend service for Plex playlist management" description = "Backend service for Plex playlist management"

1300
backend/uv.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@ services:
retries: 12 retries: 12
backend: backend:
image: ${DEPLOYABLE_BACKEND_IMAGE:-deployable-backend:local} image: ${DEPLOYABLE_BACKEND_IMAGE:-plex-playlist-backend:local}
environment: environment:
DATABASE_URL: ${DB_URL:-postgresql://plex_user:plex_password@database:5432/plex_playlist} DATABASE_URL: ${DB_URL:-postgresql://plex_user:plex_password@database:5432/plex_playlist}
ENVIRONMENT: production ENVIRONMENT: production
@@ -22,7 +22,7 @@ services:
condition: service_healthy condition: service_healthy
frontend: frontend:
image: ${DEPLOYABLE_FRONTEND_IMAGE:-deployable-frontend:local} image: ${DEPLOYABLE_FRONTEND_IMAGE:-plex-playlist-frontend:local}
depends_on: depends_on:
backend: backend:
condition: service_started condition: service_started

View File

@@ -13,7 +13,7 @@ services:
retries: 12 retries: 12
backend: backend:
image: ${DEPLOYABLE_BACKEND_IMAGE:-deployable-backend:local} image: ${DEPLOYABLE_BACKEND_IMAGE:-plex-playlist-backend:local}
environment: environment:
DATABASE_URL: ${DB_URL:-postgresql://plex_user:plex_password@database:5432/plex_playlist} DATABASE_URL: ${DB_URL:-postgresql://plex_user:plex_password@database:5432/plex_playlist}
ENVIRONMENT: production ENVIRONMENT: production

View File

@@ -72,12 +72,12 @@
### **Current Release Lifecycle (2026-07)** ### **Current Release Lifecycle (2026-07)**
- Runtime deployable images are published first to staging repositories: - Runtime deployable images are published first to staging repositories:
- `deployable-backend-staging` - `plex-playlist-backend-staging`
- `deployable-frontend-staging` - `plex-playlist-frontend-staging`
- Runtime validation (`Runtime Black-Box Integration Tests` and `End-to-End Tests`) must pass before release tagging. - Runtime validation (`Runtime Black-Box Integration Tests` and `End-to-End Tests`) must pass before release tagging.
- `Promote Release Images` retags validated staging artifacts to release repositories, but only on automated `push` runs to `main`: - `Promote Release Images` retags validated staging artifacts to release repositories, but only on automated `push` runs to `main`:
- `deployable-backend` - `plex-playlist-backend`
- `deployable-frontend` - `plex-playlist-frontend`
- Published release tags: - Published release tags:
- `latest` - `latest`
- `v<major>.<minor>.0` - `v<major>.<minor>.0`

View File

@@ -14,10 +14,10 @@ automation work under epic #66.
Lifecycle note: Lifecycle note:
- CI first builds deployable runtime artifacts in staging repositories - CI first builds deployable runtime artifacts in staging repositories
(`deployable-backend-staging`, `deployable-frontend-staging`). (`plex-playlist-backend-staging`, `plex-playlist-frontend-staging`).
- After integration and E2E validation pass, CI promotes those immutable - After integration and E2E validation pass, CI promotes those immutable
artifacts to release repositories (`deployable-backend`, artifacts to release repositories (`plex-playlist-backend`,
`deployable-frontend`) via tag promotion. `plex-playlist-frontend`) via tag promotion.
Included: Included:

View File

@@ -411,11 +411,11 @@ The pipeline is intentionally staged so expensive image jobs run only after sour
2. Source + audit lanes: 2. Source + audit lanes:
`Source Checks` and `Dependency Audits (Informational)` run after producer completion. Audit failures are intentionally non-blocking so both frontend and backend audits always report. `Source Checks` and `Dependency Audits (Informational)` run after producer completion. Audit failures are intentionally non-blocking so both frontend and backend audits always report.
3. Runtime image lanes: 3. Runtime image lanes:
`Build Release Images` publishes `deployable-backend-staging` and `deployable-frontend-staging`; `Build Tester Images` publishes integration/e2e tester images; then `Production Images Complete` gates downstream runtime tests. `Build Release Images` publishes `plex-playlist-backend-staging` and `plex-playlist-frontend-staging`; `Build Tester Images` publishes integration/e2e tester images; then `Production Images Complete` gates downstream runtime tests.
4. Runtime validation lanes: 4. Runtime validation lanes:
`Runtime Black-Box Integration Tests` and `End-to-End Tests` validate staged runtime artifacts. `Runtime Black-Box Integration Tests` and `End-to-End Tests` validate staged runtime artifacts.
5. Promotion lane: 5. Promotion lane:
`Promote Release Images` runs only for automated `push` events on `main`. It retags validated staging artifacts to release repos (`deployable-backend`, `deployable-frontend`) with `latest`, `v<major>.<minor>.0`, `v<major>.<minor>.<patch>`, and `v<major>.<minor>.<patch>-<7-char-short-sha>` tags. If the `main` commit is untagged, CI creates the next patch tag automatically; if no prior semver tag exists, the bootstrap baseline is `v0.0.0`. `Promote Release Images` runs only for automated `push` events on `main`. It retags validated staging artifacts to release repos (`plex-playlist-backend`, `plex-playlist-frontend`) with `latest`, `v<major>.<minor>.0`, `v<major>.<minor>.<patch>`, and `v<major>.<minor>.<patch>-<7-char-short-sha>` tags. If the `main` commit is untagged, CI creates the next patch tag automatically; if no prior semver tag exists, the bootstrap baseline is `v0.0.0`.
6. Postmortem lanes: 6. Postmortem lanes:
targeted postmortem jobs run when key lanes fail to capture diagnostics even when primary jobs fail early. targeted postmortem jobs run when key lanes fail to capture diagnostics even when primary jobs fail early.
@@ -433,6 +433,16 @@ Current workflow behavior includes:
For details of base/complete image build strategy, see [CI/CD Multi-Stage Build Architecture](CICD_MULTI_STAGE_BUILD.md). For details of base/complete image build strategy, see [CI/CD Multi-Stage Build Architecture](CICD_MULTI_STAGE_BUILD.md).
For incident handling, see [CI/CD Troubleshooting](CICD_TROUBLESHOOTING_GUIDE.md). For incident handling, see [CI/CD Troubleshooting](CICD_TROUBLESHOOTING_GUIDE.md).
### Renovate Manual Run Behavior
The Renovate workflow at `.gitea/workflows/renovate.yml` now treats manual dispatch as an explicit operator override:
- when triggered via `workflow_dispatch`, it forces out-of-window execution by setting `RENOVATE_IGNORE_SCHEDULE=true`
- it also sets `RENOVATE_SCHEDULE="at any time"` for the run
- it executes one single pass across enabled managers instead of splitting work into multiple manager batches
This keeps scheduled behavior unchanged while making manual runs deterministic and immediate.
### Operator Quick Reference ### Operator Quick Reference
Use workflow dispatch when you need deterministic reruns on a specific commit: Use workflow dispatch when you need deterministic reruns on a specific commit:

View File

@@ -7,8 +7,8 @@ PROJECT_NAME="${COMPOSE_PROJECT_NAME:-plex-e2e-local}"
mkdir -p "${ROOT_DIR}/frontend/.playwright-artifacts" mkdir -p "${ROOT_DIR}/frontend/.playwright-artifacts"
export DEPLOYABLE_BACKEND_IMAGE="${DEPLOYABLE_BACKEND_IMAGE:-deployable-backend:local}" export DEPLOYABLE_BACKEND_IMAGE="${DEPLOYABLE_BACKEND_IMAGE:-plex-playlist-backend:local}"
export DEPLOYABLE_FRONTEND_IMAGE="${DEPLOYABLE_FRONTEND_IMAGE:-deployable-frontend:local}" export DEPLOYABLE_FRONTEND_IMAGE="${DEPLOYABLE_FRONTEND_IMAGE:-plex-playlist-frontend:local}"
export DB_PASSWORD="${DB_PASSWORD:-plex_password}" export DB_PASSWORD="${DB_PASSWORD:-plex_password}"
export DB_URL="${DB_URL:-postgresql://plex_user:${DB_PASSWORD}@database:5432/plex_playlist}" export DB_URL="${DB_URL:-postgresql://plex_user:${DB_PASSWORD}@database:5432/plex_playlist}"
export E2E_ARTIFACT_DIR="${E2E_ARTIFACT_DIR:-${ROOT_DIR}/frontend/.playwright-artifacts}" export E2E_ARTIFACT_DIR="${E2E_ARTIFACT_DIR:-${ROOT_DIR}/frontend/.playwright-artifacts}"

View File

@@ -5,7 +5,7 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
COMPOSE_FILE="${ROOT_DIR}/compose.ci.integration.yml" COMPOSE_FILE="${ROOT_DIR}/compose.ci.integration.yml"
PROJECT_NAME="${COMPOSE_PROJECT_NAME:-plex-int-local}" PROJECT_NAME="${COMPOSE_PROJECT_NAME:-plex-int-local}"
export DEPLOYABLE_BACKEND_IMAGE="${DEPLOYABLE_BACKEND_IMAGE:-deployable-backend:local}" export DEPLOYABLE_BACKEND_IMAGE="${DEPLOYABLE_BACKEND_IMAGE:-plex-playlist-backend:local}"
export DB_PASSWORD="${DB_PASSWORD:-plex_password}" export DB_PASSWORD="${DB_PASSWORD:-plex_password}"
export DB_URL="${DB_URL:-postgresql://plex_user:${DB_PASSWORD}@database:5432/plex_playlist}" export DB_URL="${DB_URL:-postgresql://plex_user:${DB_PASSWORD}@database:5432/plex_playlist}"
@@ -15,7 +15,7 @@ cleanup() {
trap cleanup EXIT trap cleanup EXIT
echo "Running runtime integration checks against deployable backend image via compose" echo "Running runtime integration checks against plex-playlist backend image via compose"
echo "DEPLOYABLE_BACKEND_IMAGE=${DEPLOYABLE_BACKEND_IMAGE}" echo "DEPLOYABLE_BACKEND_IMAGE=${DEPLOYABLE_BACKEND_IMAGE}"
docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" up -d database backend docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" up -d database backend