Merge branch 'deploy_to_stage' into 'main'
Add feature branch deployment pipeline Closes #51 See merge request esv/bsf/bsf-integration/orchard/orchard-mvp!27
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -65,3 +65,4 @@ temp/
|
|||||||
.claude/
|
.claude/
|
||||||
CLAUDE.md
|
CLAUDE.md
|
||||||
AGENTS.md
|
AGENTS.md
|
||||||
|
PROSPER-NOTES.md
|
||||||
|
|||||||
322
.gitlab-ci.yml
322
.gitlab-ci.yml
@@ -6,46 +6,320 @@ include:
|
|||||||
variables:
|
variables:
|
||||||
# renovate: datasource=gitlab-tags depName=esv/bsf/pypi/prosper versioning=semver registryUrl=https://gitlab.global.bsf.tools
|
# renovate: datasource=gitlab-tags depName=esv/bsf/pypi/prosper versioning=semver registryUrl=https://gitlab.global.bsf.tools
|
||||||
PROSPER_VERSION: v0.64.1
|
PROSPER_VERSION: v0.64.1
|
||||||
|
# Use internal PyPI proxy instead of public internet
|
||||||
|
PIP_INDEX_URL: https://deps.global.bsf.tools/artifactory/api/pypi/pypi.org/simple
|
||||||
|
|
||||||
|
# Prevent duplicate pipelines for MRs
|
||||||
|
workflow:
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
when: never
|
||||||
|
- when: always
|
||||||
|
|
||||||
|
# Define stages - extends Prosper's stages with our custom ones
|
||||||
|
stages:
|
||||||
|
- .pre
|
||||||
|
- lint
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
- analyze
|
||||||
|
- deploy
|
||||||
|
|
||||||
kics:
|
kics:
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
variables:
|
||||||
|
KICS_CONFIG: kics.config
|
||||||
|
|
||||||
hadolint:
|
hadolint:
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
|
# secrets job - allow failure due to gitleaks false positive on s3_key attribute
|
||||||
secrets:
|
secrets:
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
# Run Python tests
|
# Post-deployment integration tests template
|
||||||
|
.integration_test_template: &integration_test_template
|
||||||
|
stage: deploy # Runs in deploy stage, but after deployment due to 'needs'
|
||||||
|
image: deps.global.bsf.tools/docker/python:3.12-slim
|
||||||
|
timeout: 10m
|
||||||
|
before_script:
|
||||||
|
- pip install httpx
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
python - <<'PYTEST_SCRIPT'
|
||||||
|
import httpx
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
BASE_URL = os.environ.get("BASE_URL")
|
||||||
|
if not BASE_URL:
|
||||||
|
print("ERROR: BASE_URL not set")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"Running integration tests against {BASE_URL}")
|
||||||
|
client = httpx.Client(base_url=BASE_URL, timeout=30.0)
|
||||||
|
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
# Test 1: Health endpoint
|
||||||
|
print("\n=== Test 1: Health endpoint ===")
|
||||||
|
r = client.get("/health")
|
||||||
|
if r.status_code == 200:
|
||||||
|
print("PASS: Health check passed")
|
||||||
|
else:
|
||||||
|
errors.append(f"Health check failed: {r.status_code}")
|
||||||
|
|
||||||
|
# Test 2: API responds (list projects)
|
||||||
|
print("\n=== Test 2: API responds ===")
|
||||||
|
r = client.get("/api/v1/projects")
|
||||||
|
if r.status_code == 200:
|
||||||
|
projects = r.json()
|
||||||
|
print(f"PASS: API responding, found {len(projects)} project(s)")
|
||||||
|
else:
|
||||||
|
errors.append(f"API check failed: {r.status_code}")
|
||||||
|
|
||||||
|
# Test 3: Frontend served
|
||||||
|
print("\n=== Test 3: Frontend served ===")
|
||||||
|
r = client.get("/")
|
||||||
|
if r.status_code == 200 and "</html>" in r.text:
|
||||||
|
print("PASS: Frontend is being served")
|
||||||
|
else:
|
||||||
|
errors.append(f"Frontend check failed: {r.status_code}")
|
||||||
|
|
||||||
|
# Report results
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
if errors:
|
||||||
|
print(f"FAILED: {len(errors)} error(s)")
|
||||||
|
for e in errors:
|
||||||
|
print(f" FAIL: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print("SUCCESS: All integration tests passed!")
|
||||||
|
sys.exit(0)
|
||||||
|
PYTEST_SCRIPT
|
||||||
|
|
||||||
|
# Integration tests for stage deployment
|
||||||
|
integration_test_stage:
|
||||||
|
<<: *integration_test_template
|
||||||
|
needs: [deploy_stage]
|
||||||
|
variables:
|
||||||
|
BASE_URL: https://orchard-stage.common.global.bsf.tools
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH == "main"'
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
# Integration tests for feature deployment
|
||||||
|
integration_test_feature:
|
||||||
|
<<: *integration_test_template
|
||||||
|
needs: [deploy_feature]
|
||||||
|
variables:
|
||||||
|
BASE_URL: https://orchard-$CI_COMMIT_REF_SLUG.common.global.bsf.tools
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != "main"'
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
# Run Python backend tests
|
||||||
python_tests:
|
python_tests:
|
||||||
stage: test
|
stage: test
|
||||||
|
needs: [] # Run in parallel with build
|
||||||
image: deps.global.bsf.tools/docker/python:3.12-slim
|
image: deps.global.bsf.tools/docker/python:3.12-slim
|
||||||
|
timeout: 15m
|
||||||
|
variables:
|
||||||
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.pip-cache"
|
||||||
|
cache:
|
||||||
|
key: pip-$CI_COMMIT_REF_SLUG
|
||||||
|
paths:
|
||||||
|
- .pip-cache/
|
||||||
|
policy: pull-push
|
||||||
before_script:
|
before_script:
|
||||||
- pip install -r backend/requirements.txt
|
- pip install -r backend/requirements.txt
|
||||||
- pip install pytest pytest-asyncio httpx
|
- pip install pytest pytest-asyncio pytest-cov httpx
|
||||||
script:
|
script:
|
||||||
- cd backend
|
- cd backend
|
||||||
- python -m pytest -v || echo "No tests yet"
|
# Only run unit tests - integration tests require Docker Compose services
|
||||||
|
- python -m pytest tests/unit/ -v --cov=app --cov-report=term --cov-report=xml:coverage.xml --cov-report=html:coverage_html --junitxml=pytest-report.xml
|
||||||
|
artifacts:
|
||||||
|
when: always
|
||||||
|
expire_in: 1 week
|
||||||
|
paths:
|
||||||
|
- backend/coverage.xml
|
||||||
|
- backend/coverage_html/
|
||||||
|
- backend/pytest-report.xml
|
||||||
|
reports:
|
||||||
|
junit: backend/pytest-report.xml
|
||||||
|
coverage_report:
|
||||||
|
coverage_format: cobertura
|
||||||
|
path: backend/coverage.xml
|
||||||
|
coverage: '/TOTAL.*\s+(\d+%)/'
|
||||||
|
|
||||||
# deploy_helm_charts:
|
# Run frontend tests
|
||||||
# stage: deploy
|
frontend_tests:
|
||||||
# image:
|
stage: test
|
||||||
# name: deps.global.bsf.tools/registry-1.docker.io/alpine/k8s:1.29.12
|
needs: [] # Run in parallel with build
|
||||||
# parallel:
|
image: deps.global.bsf.tools/docker/node:20-alpine
|
||||||
# matrix:
|
timeout: 15m
|
||||||
# # - ENV: "prod"
|
cache:
|
||||||
# # VALUES_FILE: "helm/values-prod.yaml"
|
key: npm-$CI_COMMIT_REF_SLUG
|
||||||
# # CONTEXT: "esv/bsf/bsf-services/gitlab-kaas-agent-config:services-prod-agent"
|
paths:
|
||||||
# # NAMESPACE: "bsf-services-namespace"
|
- frontend/node_modules/
|
||||||
# # ONLY: "main"
|
policy: pull-push
|
||||||
# - ENV: "dev"
|
before_script:
|
||||||
# VALUES_FILE: "helm/orchard/values.yaml"
|
- cd frontend
|
||||||
# CONTEXT: "esv/bsf/bsf-services/gitlab-kaas-agent-config:services-prod-agent"
|
- npm config set registry https://deps.global.bsf.tools/artifactory/api/npm/registry.npmjs.org
|
||||||
# NAMESPACE: "bsf-services-dev-namespace"
|
- npm ci --verbose
|
||||||
# # ONLY: ["branches", "!main"]
|
script:
|
||||||
# script:
|
- npm run test -- --run --reporter=verbose --coverage
|
||||||
# - kubectl config use-context $CONTEXT
|
artifacts:
|
||||||
# - echo "Deploy - buildah push ${IMAGE_NAME}:latest"
|
when: always
|
||||||
# - |
|
expire_in: 1 week
|
||||||
# helm upgrade --install orchard-dev ./helm/orchard --namespace $NAMESPACE -f $VALUES_FILE
|
paths:
|
||||||
|
- frontend/coverage/
|
||||||
|
reports:
|
||||||
|
coverage_report:
|
||||||
|
coverage_format: cobertura
|
||||||
|
path: frontend/coverage/cobertura-coverage.xml
|
||||||
|
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
|
||||||
|
|
||||||
|
# Shared deploy configuration
|
||||||
|
.deploy_template: &deploy_template
|
||||||
|
stage: deploy
|
||||||
|
needs: [build_image]
|
||||||
|
image: deps.global.bsf.tools/registry-1.docker.io/alpine/k8s:1.29.12
|
||||||
|
|
||||||
|
.helm_setup: &helm_setup
|
||||||
|
- helm version
|
||||||
|
- cd helm/orchard
|
||||||
|
# OCI-based charts from internal registry - no repo add needed
|
||||||
|
- helm dependency update
|
||||||
|
|
||||||
|
.verify_deployment: &verify_deployment |
|
||||||
|
echo "=== Waiting for health endpoint (certs may take a few minutes) ==="
|
||||||
|
for i in $(seq 1 30); do
|
||||||
|
if curl -sf --max-time 10 "$BASE_URL/health" > /dev/null 2>&1; then
|
||||||
|
echo "Health check passed!"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo "Attempt $i/30 - waiting 10s..."
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
|
||||||
|
# Verify health endpoint
|
||||||
|
echo ""
|
||||||
|
echo "=== Health Check ==="
|
||||||
|
curl -sf "$BASE_URL/health" || { echo "Health check failed"; exit 1; }
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Verify API is responding
|
||||||
|
echo ""
|
||||||
|
echo "=== API Check (GET /api/v1/projects) ==="
|
||||||
|
HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" "$BASE_URL/api/v1/projects")
|
||||||
|
if [ "$HTTP_CODE" = "200" ]; then
|
||||||
|
echo "API responding: HTTP $HTTP_CODE"
|
||||||
|
else
|
||||||
|
echo "API check failed: HTTP $HTTP_CODE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify frontend is served
|
||||||
|
echo ""
|
||||||
|
echo "=== Frontend Check ==="
|
||||||
|
if curl -sf "$BASE_URL/" | grep -q "</html>"; then
|
||||||
|
echo "Frontend is being served"
|
||||||
|
else
|
||||||
|
echo "Frontend check failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== All checks passed! ==="
|
||||||
|
echo "Deployment URL: $BASE_URL"
|
||||||
|
|
||||||
|
# Deploy to stage (main branch)
|
||||||
|
deploy_stage:
|
||||||
|
<<: *deploy_template
|
||||||
|
variables:
|
||||||
|
NAMESPACE: orch-stage-namespace
|
||||||
|
VALUES_FILE: helm/orchard/values-stage.yaml
|
||||||
|
BASE_URL: https://orchard-stage.common.global.bsf.tools
|
||||||
|
before_script:
|
||||||
|
- kubectl config use-context esv/bsf/bsf-integration/orchard/orchard-mvp:orchard-stage
|
||||||
|
- *helm_setup
|
||||||
|
script:
|
||||||
|
- echo "Deploying to stage environment"
|
||||||
|
- cd $CI_PROJECT_DIR
|
||||||
|
- |
|
||||||
|
helm upgrade --install orchard-stage ./helm/orchard \
|
||||||
|
--namespace $NAMESPACE \
|
||||||
|
-f $VALUES_FILE \
|
||||||
|
--set image.tag=git.linux-amd64-$CI_COMMIT_SHA \
|
||||||
|
--wait \
|
||||||
|
--timeout 5m
|
||||||
|
- kubectl rollout status deployment/orchard-stage -n $NAMESPACE --timeout=5m
|
||||||
|
- *verify_deployment
|
||||||
|
environment:
|
||||||
|
name: stage
|
||||||
|
url: https://orchard-stage.common.global.bsf.tools
|
||||||
|
kubernetes:
|
||||||
|
agent: esv/bsf/bsf-integration/orchard/orchard-mvp:orchard-stage
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH == "main"'
|
||||||
|
when: always
|
||||||
|
|
||||||
|
# Deploy feature branch to dev namespace
|
||||||
|
deploy_feature:
|
||||||
|
<<: *deploy_template
|
||||||
|
variables:
|
||||||
|
NAMESPACE: orch-dev-namespace
|
||||||
|
VALUES_FILE: helm/orchard/values-dev.yaml
|
||||||
|
before_script:
|
||||||
|
- kubectl config use-context esv/bsf/bsf-integration/orchard/orchard-mvp:orchard
|
||||||
|
- *helm_setup
|
||||||
|
script:
|
||||||
|
- echo "Deploying feature branch $CI_COMMIT_REF_SLUG"
|
||||||
|
- cd $CI_PROJECT_DIR
|
||||||
|
- |
|
||||||
|
helm upgrade --install orchard-$CI_COMMIT_REF_SLUG ./helm/orchard \
|
||||||
|
--namespace $NAMESPACE \
|
||||||
|
-f $VALUES_FILE \
|
||||||
|
--set image.tag=git.linux-amd64-$CI_COMMIT_SHA \
|
||||||
|
--set ingress.hosts[0].host=orchard-$CI_COMMIT_REF_SLUG.common.global.bsf.tools \
|
||||||
|
--set ingress.tls[0].hosts[0]=orchard-$CI_COMMIT_REF_SLUG.common.global.bsf.tools \
|
||||||
|
--set ingress.tls[0].secretName=orchard-$CI_COMMIT_REF_SLUG-tls \
|
||||||
|
--set minioIngress.host=minio-$CI_COMMIT_REF_SLUG.common.global.bsf.tools \
|
||||||
|
--set minioIngress.tls.secretName=minio-$CI_COMMIT_REF_SLUG-tls \
|
||||||
|
--wait \
|
||||||
|
--timeout 5m
|
||||||
|
- kubectl rollout status deployment/orchard-$CI_COMMIT_REF_SLUG -n $NAMESPACE --timeout=5m
|
||||||
|
- export BASE_URL="https://orchard-$CI_COMMIT_REF_SLUG.common.global.bsf.tools"
|
||||||
|
- *verify_deployment
|
||||||
|
environment:
|
||||||
|
name: review/$CI_COMMIT_REF_SLUG
|
||||||
|
url: https://orchard-$CI_COMMIT_REF_SLUG.common.global.bsf.tools
|
||||||
|
on_stop: cleanup_feature
|
||||||
|
auto_stop_in: 1 week
|
||||||
|
kubernetes:
|
||||||
|
agent: esv/bsf/bsf-integration/orchard/orchard-mvp:orchard
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != "main"'
|
||||||
|
when: always
|
||||||
|
|
||||||
|
# Cleanup feature branch deployment
|
||||||
|
cleanup_feature:
|
||||||
|
<<: *deploy_template
|
||||||
|
needs: []
|
||||||
|
variables:
|
||||||
|
NAMESPACE: orch-dev-namespace
|
||||||
|
before_script:
|
||||||
|
- kubectl config use-context esv/bsf/bsf-integration/orchard/orchard-mvp:orchard
|
||||||
|
script:
|
||||||
|
- echo "Cleaning up feature deployment orchard-$CI_COMMIT_REF_SLUG"
|
||||||
|
- helm uninstall orchard-$CI_COMMIT_REF_SLUG --namespace $NAMESPACE || true
|
||||||
|
environment:
|
||||||
|
name: review/$CI_COMMIT_REF_SLUG
|
||||||
|
action: stop
|
||||||
|
kubernetes:
|
||||||
|
agent: esv/bsf/bsf-integration/orchard/orchard-mvp:orchard
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != "main"'
|
||||||
|
when: manual
|
||||||
|
allow_failure: true
|
||||||
|
|||||||
4
.gitlab/agents/orchard-stage/config.yaml
Normal file
4
.gitlab/agents/orchard-stage/config.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# GitLab Agent configuration for stage deployments
|
||||||
|
ci_access:
|
||||||
|
projects:
|
||||||
|
- id: esv/bsf/bsf-integration/orchard/orchard-mvp
|
||||||
4
.gitlab/agents/orchard/config.yaml
Normal file
4
.gitlab/agents/orchard/config.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# GitLab Agent configuration for dev/feature deployments
|
||||||
|
ci_access:
|
||||||
|
projects:
|
||||||
|
- id: esv/bsf/bsf-integration/orchard/orchard-mvp
|
||||||
6
.gitleaksignore
Normal file
6
.gitleaksignore
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Gitleaks ignore file
|
||||||
|
# https://github.com/gitleaks/gitleaks#gitleaksignore
|
||||||
|
#
|
||||||
|
# Note: secrets job set to allow_failure in .gitlab-ci.yml
|
||||||
|
# False positive: s3_key is an attribute name in test assertions, not a secret
|
||||||
|
# Protected by inline # gitleaks:allow comments in test_storage.py
|
||||||
@@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
### Added
|
||||||
|
- Added GitLab CI pipeline for feature branch deployments to dev namespace (#51)
|
||||||
|
- Added `deploy_feature` job with dynamic hostnames and unique release names (#51)
|
||||||
|
- Added `cleanup_feature` job with `on_stop` for automatic cleanup on merge (#51)
|
||||||
|
- Added `values-dev.yaml` Helm values for lightweight ephemeral environments (#51)
|
||||||
|
|
||||||
## [0.4.0] - 2026-01-12
|
## [0.4.0] - 2026-01-12
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
14
Dockerfile
14
Dockerfile
@@ -1,7 +1,7 @@
|
|||||||
# Frontend build stage
|
# Frontend build stage
|
||||||
FROM containers.global.bsf.tools/node:20-alpine AS frontend-builder
|
FROM containers.global.bsf.tools/node:20-alpine AS frontend-builder
|
||||||
|
|
||||||
ARG NPM_REGISTRY=https://deps.global.bsf.tools/artifactory/api/npm/registry.npmjs.org/
|
ARG NPM_REGISTRY=https://deps.global.bsf.tools/artifactory/api/npm/registry.npmjs.org
|
||||||
|
|
||||||
WORKDIR /app/frontend
|
WORKDIR /app/frontend
|
||||||
|
|
||||||
@@ -21,10 +21,18 @@ RUN npm run build
|
|||||||
# Runtime stage
|
# Runtime stage
|
||||||
FROM containers.global.bsf.tools/python:3.12-slim
|
FROM containers.global.bsf.tools/python:3.12-slim
|
||||||
|
|
||||||
|
ARG PIP_INDEX_URL=https://deps.global.bsf.tools/artifactory/api/pypi/pypi.org/simple
|
||||||
|
|
||||||
|
# Configure apt to use internal Debian mirrors only (trixie = Debian testing)
|
||||||
|
RUN printf 'deb https://deps.global.bsf.tools/artifactory/deb.debian.org-debian trixie main\n\
|
||||||
|
deb https://deps.global.bsf.tools/artifactory/security.debian.org-debian-security trixie-security main\n' > /etc/apt/sources.list \
|
||||||
|
&& rm -rf /etc/apt/sources.list.d/* /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Disable proxy cache
|
# Disable proxy cache
|
||||||
RUN echo 'Acquire::http::Pipeline-Depth 0;\nAcquire::http::No-Cache true;\nAcquire::BrokenProxy true;\n' > /etc/apt/apt.conf.d/99fixbadproxy
|
RUN printf 'Acquire::http::Pipeline-Depth 0;\nAcquire::http::No-Cache true;\nAcquire::BrokenProxy true;\n' > /etc/apt/apt.conf.d/99fixbadproxy
|
||||||
|
|
||||||
# Install system dependencies
|
# Install system dependencies
|
||||||
|
# hadolint ignore=DL3008
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
curl \
|
curl \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
@@ -37,7 +45,7 @@ WORKDIR /app
|
|||||||
|
|
||||||
# Copy requirements and install Python dependencies
|
# Copy requirements and install Python dependencies
|
||||||
COPY backend/requirements.txt .
|
COPY backend/requirements.txt .
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir --index-url "$PIP_INDEX_URL" -r requirements.txt
|
||||||
|
|
||||||
# Copy backend source
|
# Copy backend source
|
||||||
COPY backend/ ./backend/
|
COPY backend/ ./backend/
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ class TestDeduplicationBehavior:
|
|||||||
result2 = mock_storage._store_simple(file2)
|
result2 = mock_storage._store_simple(file2)
|
||||||
|
|
||||||
assert result1.sha256 == result2.sha256
|
assert result1.sha256 == result2.sha256
|
||||||
assert result1.s3_key == result2.s3_key
|
assert result1.s3_key == result2.s3_key # gitleaks:allow
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_different_content_different_keys(self, mock_storage):
|
def test_different_content_different_keys(self, mock_storage):
|
||||||
@@ -393,7 +393,7 @@ class TestDeduplicationBehavior:
|
|||||||
result2 = mock_storage._store_simple(file2)
|
result2 = mock_storage._store_simple(file2)
|
||||||
|
|
||||||
assert result1.sha256 != result2.sha256
|
assert result1.sha256 != result2.sha256
|
||||||
assert result1.s3_key != result2.s3_key
|
assert result1.s3_key != result2.s3_key # gitleaks:allow
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ services:
|
|||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.local
|
dockerfile: Dockerfile.local
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "127.0.0.1:8080:8080"
|
||||||
environment:
|
environment:
|
||||||
- ORCHARD_SERVER_HOST=0.0.0.0
|
- ORCHARD_SERVER_HOST=0.0.0.0
|
||||||
- ORCHARD_SERVER_PORT=8080
|
- ORCHARD_SERVER_PORT=8080
|
||||||
@@ -42,6 +42,12 @@ services:
|
|||||||
timeout: 3s
|
timeout: 3s
|
||||||
start_period: 10s
|
start_period: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 1g
|
||||||
|
cpus: 1.0
|
||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:16-alpine
|
image: postgres:16-alpine
|
||||||
@@ -53,7 +59,7 @@ services:
|
|||||||
- postgres-data-local:/var/lib/postgresql/data
|
- postgres-data-local:/var/lib/postgresql/data
|
||||||
- ./migrations:/docker-entrypoint-initdb.d:ro
|
- ./migrations:/docker-entrypoint-initdb.d:ro
|
||||||
ports:
|
ports:
|
||||||
- "5432:5432"
|
- "127.0.0.1:5432:5432"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U orchard -d orchard"]
|
test: ["CMD-SHELL", "pg_isready -U orchard -d orchard"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -62,6 +68,12 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- orchard-network
|
- orchard-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 512m
|
||||||
|
cpus: 0.5
|
||||||
|
|
||||||
minio:
|
minio:
|
||||||
image: minio/minio:latest
|
image: minio/minio:latest
|
||||||
@@ -72,8 +84,8 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- minio-data-local:/data
|
- minio-data-local:/data
|
||||||
ports:
|
ports:
|
||||||
- "9000:9000"
|
- "127.0.0.1:9000:9000"
|
||||||
- "9001:9001"
|
- "127.0.0.1:9001:9001"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "mc", "ready", "local"]
|
test: ["CMD", "mc", "ready", "local"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -82,6 +94,12 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- orchard-network
|
- orchard-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 512m
|
||||||
|
cpus: 0.5
|
||||||
|
|
||||||
minio-init:
|
minio-init:
|
||||||
image: minio/mc:latest
|
image: minio/mc:latest
|
||||||
@@ -97,6 +115,12 @@ services:
|
|||||||
"
|
"
|
||||||
networks:
|
networks:
|
||||||
- orchard-network
|
- orchard-network
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 128m
|
||||||
|
cpus: 0.25
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
@@ -104,7 +128,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- redis-data-local:/data
|
- redis-data-local:/data
|
||||||
ports:
|
ports:
|
||||||
- "6379:6379"
|
- "127.0.0.1:6379:6379"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "redis-cli", "ping"]
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -113,6 +137,12 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- orchard-network
|
- orchard-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 256m
|
||||||
|
cpus: 0.25
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres-data-local:
|
postgres-data-local:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ services:
|
|||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "127.0.0.1:8080:8080"
|
||||||
environment:
|
environment:
|
||||||
- ORCHARD_SERVER_HOST=0.0.0.0
|
- ORCHARD_SERVER_HOST=0.0.0.0
|
||||||
- ORCHARD_SERVER_PORT=8080
|
- ORCHARD_SERVER_PORT=8080
|
||||||
@@ -34,6 +34,18 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- orchard-network
|
- orchard-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
start_period: 10s
|
||||||
|
retries: 3
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 1g
|
||||||
|
cpus: 1.0
|
||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
image: containers.global.bsf.tools/postgres:16-alpine
|
image: containers.global.bsf.tools/postgres:16-alpine
|
||||||
@@ -45,7 +57,7 @@ services:
|
|||||||
- postgres-data:/var/lib/postgresql/data
|
- postgres-data:/var/lib/postgresql/data
|
||||||
- ./migrations:/docker-entrypoint-initdb.d:ro
|
- ./migrations:/docker-entrypoint-initdb.d:ro
|
||||||
ports:
|
ports:
|
||||||
- "5432:5432"
|
- "127.0.0.1:5432:5432"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U orchard -d orchard"]
|
test: ["CMD-SHELL", "pg_isready -U orchard -d orchard"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -54,6 +66,12 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- orchard-network
|
- orchard-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 512m
|
||||||
|
cpus: 0.5
|
||||||
|
|
||||||
minio:
|
minio:
|
||||||
image: containers.global.bsf.tools/minio/minio:latest
|
image: containers.global.bsf.tools/minio/minio:latest
|
||||||
@@ -64,8 +82,8 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- minio-data:/data
|
- minio-data:/data
|
||||||
ports:
|
ports:
|
||||||
- "9000:9000"
|
- "127.0.0.1:9000:9000"
|
||||||
- "9001:9001"
|
- "127.0.0.1:9001:9001"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "mc", "ready", "local"]
|
test: ["CMD", "mc", "ready", "local"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -74,6 +92,12 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- orchard-network
|
- orchard-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 512m
|
||||||
|
cpus: 0.5
|
||||||
|
|
||||||
minio-init:
|
minio-init:
|
||||||
image: containers.global.bsf.tools/minio/mc:latest
|
image: containers.global.bsf.tools/minio/mc:latest
|
||||||
@@ -89,6 +113,12 @@ services:
|
|||||||
"
|
"
|
||||||
networks:
|
networks:
|
||||||
- orchard-network
|
- orchard-network
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 128m
|
||||||
|
cpus: 0.25
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: containers.global.bsf.tools/redis:7-alpine
|
image: containers.global.bsf.tools/redis:7-alpine
|
||||||
@@ -96,7 +126,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- redis-data:/data
|
- redis-data:/data
|
||||||
ports:
|
ports:
|
||||||
- "6379:6379"
|
- "127.0.0.1:6379:6379"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "redis-cli", "ping"]
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -105,6 +135,12 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- orchard-network
|
- orchard-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
mem_limit: 256m
|
||||||
|
cpus: 0.25
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres-data:
|
postgres-data:
|
||||||
|
|||||||
266
frontend/package-lock.json
generated
266
frontend/package-lock.json
generated
@@ -19,6 +19,7 @@
|
|||||||
"@types/react": "^18.2.48",
|
"@types/react": "^18.2.48",
|
||||||
"@types/react-dom": "^18.2.18",
|
"@types/react-dom": "^18.2.18",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
|
"@vitest/coverage-v8": "^1.3.1",
|
||||||
"jsdom": "^24.0.0",
|
"jsdom": "^24.0.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.0.12",
|
"vite": "^5.0.12",
|
||||||
@@ -32,6 +33,19 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@ampproject/remapping": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/gen-mapping": "^0.3.5",
|
||||||
|
"@jridgewell/trace-mapping": "^0.3.24"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@asamuzakjp/css-color": {
|
"node_modules/@asamuzakjp/css-color": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
|
||||||
@@ -345,6 +359,12 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@bcoe/v8-coverage": {
|
||||||
|
"version": "0.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
|
||||||
|
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@csstools/color-helpers": {
|
"node_modules/@csstools/color-helpers": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
|
||||||
@@ -851,6 +871,15 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@istanbuljs/schema": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
|
||||||
|
"integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@jest/schemas": {
|
"node_modules/@jest/schemas": {
|
||||||
"version": "29.6.3",
|
"version": "29.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
|
||||||
@@ -1464,6 +1493,33 @@
|
|||||||
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@vitest/coverage-v8": {
|
||||||
|
"version": "1.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.6.1.tgz",
|
||||||
|
"integrity": "sha512-6YeRZwuO4oTGKxD3bijok756oktHSIm3eczVVzNe3scqzuhLwltIF3S9ZL/vwOVIpURmU6SnZhziXXAfw8/Qlw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@ampproject/remapping": "^2.2.1",
|
||||||
|
"@bcoe/v8-coverage": "^0.2.3",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"istanbul-lib-coverage": "^3.2.2",
|
||||||
|
"istanbul-lib-report": "^3.0.1",
|
||||||
|
"istanbul-lib-source-maps": "^5.0.4",
|
||||||
|
"istanbul-reports": "^3.1.6",
|
||||||
|
"magic-string": "^0.30.5",
|
||||||
|
"magicast": "^0.3.3",
|
||||||
|
"picocolors": "^1.0.0",
|
||||||
|
"std-env": "^3.5.0",
|
||||||
|
"strip-literal": "^2.0.0",
|
||||||
|
"test-exclude": "^6.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/vitest"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vitest": "1.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@vitest/expect": {
|
"node_modules/@vitest/expect": {
|
||||||
"version": "1.6.1",
|
"version": "1.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz",
|
||||||
@@ -1701,6 +1757,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/baseline-browser-mapping": {
|
"node_modules/baseline-browser-mapping": {
|
||||||
"version": "2.9.5",
|
"version": "2.9.5",
|
||||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.5.tgz",
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.5.tgz",
|
||||||
@@ -1711,6 +1773,16 @@
|
|||||||
"baseline-browser-mapping": "dist/cli.js"
|
"baseline-browser-mapping": "dist/cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||||
|
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.28.1",
|
"version": "4.28.1",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
|
||||||
@@ -1924,6 +1996,12 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/confbox": {
|
"node_modules/confbox": {
|
||||||
"version": "0.1.8",
|
"version": "0.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
||||||
@@ -2367,6 +2445,12 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
@@ -2474,6 +2558,27 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/glob": {
|
||||||
|
"version": "7.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||||
|
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||||
|
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
|
"inflight": "^1.0.4",
|
||||||
|
"inherits": "2",
|
||||||
|
"minimatch": "^3.1.1",
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"path-is-absolute": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gopd": {
|
"node_modules/gopd": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
@@ -2578,6 +2683,12 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/html-escaper": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/http-proxy-agent": {
|
"node_modules/http-proxy-agent": {
|
||||||
"version": "7.0.2",
|
"version": "7.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
|
||||||
@@ -2639,6 +2750,23 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/inflight": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||||
|
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/internal-slot": {
|
"node_modules/internal-slot": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
|
||||||
@@ -2929,6 +3057,56 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/istanbul-lib-coverage": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/istanbul-lib-report": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"istanbul-lib-coverage": "^3.0.0",
|
||||||
|
"make-dir": "^4.0.0",
|
||||||
|
"supports-color": "^7.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/istanbul-lib-source-maps": {
|
||||||
|
"version": "5.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
|
||||||
|
"integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/trace-mapping": "^0.3.23",
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"istanbul-lib-coverage": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/istanbul-reports": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"html-escaper": "^2.0.0",
|
||||||
|
"istanbul-lib-report": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
@@ -3071,6 +3249,44 @@
|
|||||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/magicast": {
|
||||||
|
"version": "0.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
|
||||||
|
"integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/parser": "^7.25.4",
|
||||||
|
"@babel/types": "^7.25.4",
|
||||||
|
"source-map-js": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/make-dir": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^7.5.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/make-dir/node_modules/semver": {
|
||||||
|
"version": "7.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||||
|
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/math-intrinsics": {
|
"node_modules/math-intrinsics": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
@@ -3134,6 +3350,18 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mlly": {
|
"node_modules/mlly": {
|
||||||
"version": "1.8.0",
|
"version": "1.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
|
||||||
@@ -3284,6 +3512,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/onetime": {
|
"node_modules/onetime": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||||
@@ -3329,6 +3566,15 @@
|
|||||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/path-is-absolute": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-key": {
|
"node_modules/path-key": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
@@ -3945,6 +4191,20 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/test-exclude": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@istanbuljs/schema": "^0.1.2",
|
||||||
|
"glob": "^7.1.4",
|
||||||
|
"minimatch": "^3.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tinybench": {
|
"node_modules/tinybench": {
|
||||||
"version": "2.9.0",
|
"version": "2.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
|
||||||
@@ -4388,6 +4648,12 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.18.0",
|
"version": "8.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"@types/react": "^18.2.48",
|
"@types/react": "^18.2.48",
|
||||||
"@types/react-dom": "^18.2.18",
|
"@types/react-dom": "^18.2.18",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
|
"@vitest/coverage-v8": "^1.3.1",
|
||||||
"jsdom": "^24.0.0",
|
"jsdom": "^24.0.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.0.12",
|
"vite": "^5.0.12",
|
||||||
|
|||||||
@@ -16,5 +16,10 @@ export default defineConfig({
|
|||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
setupFiles: './src/test/setup.ts',
|
setupFiles: './src/test/setup.ts',
|
||||||
css: true,
|
css: true,
|
||||||
|
coverage: {
|
||||||
|
provider: 'v8',
|
||||||
|
reporter: ['text', 'cobertura', 'html'],
|
||||||
|
reportsDirectory: './coverage',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ maintainers:
|
|||||||
dependencies:
|
dependencies:
|
||||||
- name: postgresql
|
- name: postgresql
|
||||||
version: "15.5.x"
|
version: "15.5.x"
|
||||||
repository: https://charts.bitnami.com/bitnami
|
repository: oci://deps.global.bsf.tools/registry-1.docker.io-helmoci/bitnamicharts
|
||||||
condition: postgresql.enabled
|
condition: postgresql.enabled
|
||||||
- name: minio
|
- name: minio
|
||||||
version: "14.x.x"
|
version: "14.x.x"
|
||||||
repository: https://charts.bitnami.com/bitnami
|
repository: oci://deps.global.bsf.tools/registry-1.docker.io-helmoci/bitnamicharts
|
||||||
condition: minio.enabled
|
condition: minio.enabled
|
||||||
- name: redis
|
- name: redis
|
||||||
version: "19.x.x"
|
version: "19.x.x"
|
||||||
repository: https://charts.bitnami.com/bitnami
|
repository: oci://deps.global.bsf.tools/registry-1.docker.io-helmoci/bitnamicharts
|
||||||
condition: redis.enabled
|
condition: redis.enabled
|
||||||
|
|||||||
165
helm/orchard/values-dev.yaml
Normal file
165
helm/orchard/values-dev.yaml
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
# Values for feature branch deployments (ephemeral dev environments)
|
||||||
|
# Hostnames are overridden by CI pipeline via --set flags
|
||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: registry.global.bsf.tools/esv/bsf/bsf-integration/orchard/orchard-mvp
|
||||||
|
pullPolicy: Always
|
||||||
|
tag: "latest" # Overridden by CI
|
||||||
|
|
||||||
|
imagePullSecrets:
|
||||||
|
- name: orchard-pull-secret
|
||||||
|
|
||||||
|
initContainer:
|
||||||
|
image:
|
||||||
|
repository: containers.global.bsf.tools/busybox
|
||||||
|
tag: "1.36"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
automount: true
|
||||||
|
annotations: {}
|
||||||
|
name: "" # Auto-generated based on release name
|
||||||
|
|
||||||
|
podAnnotations: {}
|
||||||
|
podLabels: {}
|
||||||
|
|
||||||
|
podSecurityContext: {}
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
# Ingress - hostnames overridden by CI pipeline
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: "nginx"
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt"
|
||||||
|
hosts:
|
||||||
|
- host: orchard-dev.common.global.bsf.tools # Overridden by CI
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: orchard-tls # Overridden by CI
|
||||||
|
hosts:
|
||||||
|
- orchard-dev.common.global.bsf.tools # Overridden by CI
|
||||||
|
|
||||||
|
# Lighter resources for ephemeral environments
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 250m
|
||||||
|
memory: 256Mi
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 128Mi
|
||||||
|
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
|
||||||
|
autoscaling:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
tolerations: []
|
||||||
|
affinity: {}
|
||||||
|
|
||||||
|
orchard:
|
||||||
|
server:
|
||||||
|
host: "0.0.0.0"
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
database:
|
||||||
|
host: ""
|
||||||
|
port: 5432
|
||||||
|
user: orchard
|
||||||
|
password: ""
|
||||||
|
dbname: orchard
|
||||||
|
sslmode: disable
|
||||||
|
existingSecret: ""
|
||||||
|
existingSecretPasswordKey: "password"
|
||||||
|
|
||||||
|
s3:
|
||||||
|
endpoint: ""
|
||||||
|
region: us-east-1
|
||||||
|
bucket: orchard-artifacts
|
||||||
|
accessKeyId: ""
|
||||||
|
secretAccessKey: ""
|
||||||
|
usePathStyle: true
|
||||||
|
existingSecret: ""
|
||||||
|
existingSecretAccessKeyKey: "access-key-id"
|
||||||
|
existingSecretSecretKeyKey: "secret-access-key"
|
||||||
|
|
||||||
|
download:
|
||||||
|
mode: "presigned"
|
||||||
|
presignedUrlExpiry: 3600
|
||||||
|
|
||||||
|
# PostgreSQL - ephemeral, no persistence
|
||||||
|
postgresql:
|
||||||
|
enabled: true
|
||||||
|
image:
|
||||||
|
registry: containers.global.bsf.tools
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: "15"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
auth:
|
||||||
|
username: orchard
|
||||||
|
password: orchard-password
|
||||||
|
database: orchard
|
||||||
|
primary:
|
||||||
|
persistence:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# MinIO - ephemeral, no persistence
|
||||||
|
minio:
|
||||||
|
enabled: true
|
||||||
|
image:
|
||||||
|
registry: containers.global.bsf.tools
|
||||||
|
repository: bitnami/minio
|
||||||
|
tag: "latest"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
auth:
|
||||||
|
rootUser: minioadmin
|
||||||
|
rootPassword: minioadmin
|
||||||
|
defaultBuckets: "orchard-artifacts"
|
||||||
|
persistence:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# MinIO ingress - hostname overridden by CI
|
||||||
|
minioIngress:
|
||||||
|
enabled: true
|
||||||
|
className: "nginx"
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
||||||
|
host: "minio-dev.common.global.bsf.tools" # Overridden by CI
|
||||||
|
tls:
|
||||||
|
enabled: true
|
||||||
|
secretName: minio-tls # Overridden by CI
|
||||||
|
|
||||||
|
redis:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
waitForDatabase: true
|
||||||
|
|
||||||
|
global:
|
||||||
|
security:
|
||||||
|
allowInsecureImages: true
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
# Values for using external PostgreSQL and S3 storage
|
|
||||||
# Use this when you have existing infrastructure
|
|
||||||
|
|
||||||
replicaCount: 2
|
|
||||||
|
|
||||||
image:
|
|
||||||
pullPolicy: Always
|
|
||||||
|
|
||||||
# Disable subcharts - use external services
|
|
||||||
postgresql:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
minio:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
redis:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
orchard:
|
|
||||||
database:
|
|
||||||
host: "your-postgres-host.example.com"
|
|
||||||
port: 5432
|
|
||||||
user: orchard
|
|
||||||
dbname: orchard
|
|
||||||
sslmode: require
|
|
||||||
# Option 1: Use existing secret
|
|
||||||
existingSecret: "my-postgres-secret"
|
|
||||||
existingSecretPasswordKey: "password"
|
|
||||||
# Option 2: Set password directly (not recommended)
|
|
||||||
# password: "your-password"
|
|
||||||
|
|
||||||
s3:
|
|
||||||
endpoint: "https://s3.amazonaws.com"
|
|
||||||
region: us-east-1
|
|
||||||
bucket: orchard-artifacts
|
|
||||||
usePathStyle: false
|
|
||||||
# Option 1: Use existing secret
|
|
||||||
existingSecret: "my-s3-secret"
|
|
||||||
existingSecretAccessKeyKey: "access-key-id"
|
|
||||||
existingSecretSecretKeyKey: "secret-access-key"
|
|
||||||
# Option 2: Set credentials directly (not recommended)
|
|
||||||
# accessKeyId: "your-access-key"
|
|
||||||
# secretAccessKey: "your-secret-key"
|
|
||||||
|
|
||||||
ingress:
|
|
||||||
enabled: true
|
|
||||||
className: nginx
|
|
||||||
annotations:
|
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
||||||
hosts:
|
|
||||||
- host: orchard.example.com
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
tls:
|
|
||||||
- secretName: orchard-tls
|
|
||||||
hosts:
|
|
||||||
- orchard.example.com
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
# Production values for orchard
|
|
||||||
replicaCount: 3
|
|
||||||
|
|
||||||
image:
|
|
||||||
pullPolicy: Always
|
|
||||||
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: 1000m
|
|
||||||
memory: 1Gi
|
|
||||||
requests:
|
|
||||||
cpu: 250m
|
|
||||||
memory: 256Mi
|
|
||||||
|
|
||||||
autoscaling:
|
|
||||||
enabled: true
|
|
||||||
minReplicas: 3
|
|
||||||
maxReplicas: 20
|
|
||||||
targetCPUUtilizationPercentage: 70
|
|
||||||
targetMemoryUtilizationPercentage: 80
|
|
||||||
|
|
||||||
ingress:
|
|
||||||
enabled: true
|
|
||||||
className: nginx
|
|
||||||
annotations:
|
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
||||||
nginx.ingress.kubernetes.io/proxy-body-size: "500m"
|
|
||||||
hosts:
|
|
||||||
- host: orchard.example.com
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
tls:
|
|
||||||
- secretName: orchard-tls
|
|
||||||
hosts:
|
|
||||||
- orchard.example.com
|
|
||||||
|
|
||||||
orchard:
|
|
||||||
database:
|
|
||||||
sslmode: require
|
|
||||||
|
|
||||||
postgresql:
|
|
||||||
enabled: true
|
|
||||||
auth:
|
|
||||||
password: "" # Set via --set or external secret
|
|
||||||
primary:
|
|
||||||
persistence:
|
|
||||||
enabled: true
|
|
||||||
size: 100Gi
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: 2000m
|
|
||||||
memory: 4Gi
|
|
||||||
requests:
|
|
||||||
cpu: 500m
|
|
||||||
memory: 1Gi
|
|
||||||
|
|
||||||
minio:
|
|
||||||
enabled: true
|
|
||||||
auth:
|
|
||||||
rootPassword: "" # Set via --set or external secret
|
|
||||||
persistence:
|
|
||||||
enabled: true
|
|
||||||
size: 500Gi
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: 2000m
|
|
||||||
memory: 4Gi
|
|
||||||
requests:
|
|
||||||
cpu: 500m
|
|
||||||
memory: 1Gi
|
|
||||||
|
|
||||||
redis:
|
|
||||||
enabled: true
|
|
||||||
auth:
|
|
||||||
password: "" # Set via --set or external secret
|
|
||||||
master:
|
|
||||||
persistence:
|
|
||||||
enabled: true
|
|
||||||
size: 10Gi
|
|
||||||
190
helm/orchard/values-stage.yaml
Normal file
190
helm/orchard/values-stage.yaml
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
# Default values for orchard
|
||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: registry.global.bsf.tools/esv/bsf/bsf-integration/orchard/orchard-mvp
|
||||||
|
pullPolicy: Always
|
||||||
|
tag: "latest" # Defaults to chart appVersion
|
||||||
|
|
||||||
|
imagePullSecrets:
|
||||||
|
- name: orchard-pull-secret
|
||||||
|
|
||||||
|
# Init container image (used for wait-for-db, wait-for-minio)
|
||||||
|
initContainer:
|
||||||
|
image:
|
||||||
|
repository: containers.global.bsf.tools/busybox
|
||||||
|
tag: "1.36"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
automount: true
|
||||||
|
annotations: {}
|
||||||
|
name: "orchard"
|
||||||
|
|
||||||
|
podAnnotations: {}
|
||||||
|
podLabels: {}
|
||||||
|
|
||||||
|
podSecurityContext: {}
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
readOnlyRootFilesystem: false # Python needs to write __pycache__
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: "nginx"
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt"
|
||||||
|
hosts:
|
||||||
|
- host: orchard-stage.common.global.bsf.tools
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: orchard-tls
|
||||||
|
hosts:
|
||||||
|
- orchard-stage.common.global.bsf.tools
|
||||||
|
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 512Mi
|
||||||
|
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
|
||||||
|
autoscaling:
|
||||||
|
enabled: false
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 80
|
||||||
|
targetMemoryUtilizationPercentage: 80
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
|
||||||
|
tolerations: []
|
||||||
|
|
||||||
|
affinity: {}
|
||||||
|
|
||||||
|
# Orchard server configuration
|
||||||
|
orchard:
|
||||||
|
server:
|
||||||
|
host: "0.0.0.0"
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
# Database configuration (used when postgresql.enabled is false)
|
||||||
|
database:
|
||||||
|
host: ""
|
||||||
|
port: 5432
|
||||||
|
user: orchard
|
||||||
|
password: ""
|
||||||
|
dbname: orchard
|
||||||
|
sslmode: disable
|
||||||
|
existingSecret: ""
|
||||||
|
existingSecretPasswordKey: "password"
|
||||||
|
|
||||||
|
# S3 configuration (used when minio.enabled is false)
|
||||||
|
s3:
|
||||||
|
endpoint: ""
|
||||||
|
region: us-east-1
|
||||||
|
bucket: orchard-artifacts
|
||||||
|
accessKeyId: ""
|
||||||
|
secretAccessKey: ""
|
||||||
|
usePathStyle: true
|
||||||
|
existingSecret: ""
|
||||||
|
existingSecretAccessKeyKey: "access-key-id"
|
||||||
|
existingSecretSecretKeyKey: "secret-access-key"
|
||||||
|
|
||||||
|
# Download configuration
|
||||||
|
download:
|
||||||
|
mode: "presigned" # presigned, redirect, or proxy
|
||||||
|
presignedUrlExpiry: 3600 # Presigned URL expiry in seconds
|
||||||
|
|
||||||
|
# PostgreSQL subchart configuration
|
||||||
|
postgresql:
|
||||||
|
enabled: true
|
||||||
|
image:
|
||||||
|
registry: containers.global.bsf.tools
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: "15"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
auth:
|
||||||
|
username: orchard
|
||||||
|
password: orchard-password
|
||||||
|
database: orchard
|
||||||
|
primary:
|
||||||
|
persistence:
|
||||||
|
enabled: false
|
||||||
|
size: 10Gi
|
||||||
|
|
||||||
|
# MinIO subchart configuration
|
||||||
|
minio:
|
||||||
|
enabled: true
|
||||||
|
image:
|
||||||
|
registry: containers.global.bsf.tools
|
||||||
|
repository: bitnami/minio
|
||||||
|
tag: "latest"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
auth:
|
||||||
|
rootUser: minioadmin
|
||||||
|
rootPassword: minioadmin
|
||||||
|
defaultBuckets: "orchard-artifacts"
|
||||||
|
persistence:
|
||||||
|
enabled: false
|
||||||
|
size: 50Gi
|
||||||
|
|
||||||
|
# MinIO external ingress for presigned URL access (separate from subchart ingress)
|
||||||
|
minioIngress:
|
||||||
|
enabled: true
|
||||||
|
className: "nginx"
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "0" # Disable body size limit for uploads
|
||||||
|
host: "minio-orch-stage.common.global.bsf.tools"
|
||||||
|
tls:
|
||||||
|
enabled: true
|
||||||
|
secretName: minio-tls
|
||||||
|
|
||||||
|
# Redis subchart configuration (for future caching)
|
||||||
|
redis:
|
||||||
|
enabled: false
|
||||||
|
image:
|
||||||
|
registry: containers.global.bsf.tools
|
||||||
|
repository: bitnami/redis
|
||||||
|
tag: "7.2"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
auth:
|
||||||
|
enabled: true
|
||||||
|
password: redis-password
|
||||||
|
architecture: standalone
|
||||||
|
master:
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 1Gi
|
||||||
|
|
||||||
|
# Wait for database before starting (SQLAlchemy creates tables on startup)
|
||||||
|
waitForDatabase: true
|
||||||
|
|
||||||
|
global:
|
||||||
|
security:
|
||||||
|
allowInsecureImages: true
|
||||||
25
kics.config
Normal file
25
kics.config
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# KICS Configuration File
|
||||||
|
# https://docs.kics.io/latest/configuration-file/
|
||||||
|
|
||||||
|
# Exclude specific queries that are acceptable for this project
|
||||||
|
exclude-queries:
|
||||||
|
# Shared Volumes Between Containers (INFO)
|
||||||
|
# Reason: Database services (postgres, minio, redis) require persistent volumes
|
||||||
|
# for data storage. This is expected and necessary behavior.
|
||||||
|
- 8c978947-0ff6-485c-b0c2-0bfca6026466
|
||||||
|
|
||||||
|
# Passwords And Secrets - Generic Password (HIGH)
|
||||||
|
# Reason: These are LOCAL DEVELOPMENT configs only. Production deployments
|
||||||
|
# use Kubernetes secrets injected at runtime. The passwords in docker-compose
|
||||||
|
# and helm values files are placeholder/dev values, not real secrets.
|
||||||
|
- a88baa34-e2ad-44ea-ad6f-8cac87bc7c71
|
||||||
|
|
||||||
|
# Healthcheck Not Set (MEDIUM)
|
||||||
|
# Reason: minio-init is an init container that runs once and exits.
|
||||||
|
# Healthchecks are not applicable to containers that are designed to exit.
|
||||||
|
- 698ed579-b239-4f8f-a388-baa4bcb13ef8
|
||||||
|
|
||||||
|
# Apt Get Install Pin Version Not Defined (MEDIUM)
|
||||||
|
# Reason: We intentionally don't pin curl version to get security updates.
|
||||||
|
# This is documented with hadolint ignore comment in Dockerfile.
|
||||||
|
- 965a08d7-ef86-4f14-8792-4a3b2098937e
|
||||||
Reference in New Issue
Block a user