ci: migrate community workflows to gitea
CI / Rust Checks (push) Has been cancelled
CI / UI Checks (push) Has been cancelled
CI / Frontend E2E (push) Has been cancelled
CI / Deployment Manifests (push) Has been cancelled
Deploy / build-images (apps/admin-api/Dockerfile, git.itexp.me/bsodfather/crank-community-admin-api, admin-api) (push) Has been cancelled
Deploy / build-images (apps/mcp-server/Dockerfile, git.itexp.me/bsodfather/crank-community-mcp-server, mcp-server) (push) Has been cancelled
Deploy / build-images (apps/ui/Dockerfile, git.itexp.me/bsodfather/crank-community-ui, ui) (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
CI / Rust Checks (push) Has been cancelled
CI / UI Checks (push) Has been cancelled
CI / Frontend E2E (push) Has been cancelled
CI / Deployment Manifests (push) Has been cancelled
Deploy / build-images (apps/admin-api/Dockerfile, git.itexp.me/bsodfather/crank-community-admin-api, admin-api) (push) Has been cancelled
Deploy / build-images (apps/mcp-server/Dockerfile, git.itexp.me/bsodfather/crank-community-mcp-server, mcp-server) (push) Has been cancelled
Deploy / build-images (apps/ui/Dockerfile, git.itexp.me/bsodfather/crank-community-ui, ui) (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
This commit is contained in:
@@ -7,10 +7,6 @@ on:
|
||||
- main
|
||||
- "feat/**"
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
rust:
|
||||
name: Rust Checks
|
||||
@@ -36,11 +32,12 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: 1.85.0
|
||||
components: rustfmt, clippy
|
||||
- name: Verify runner toolchain
|
||||
run: |
|
||||
rustc --version
|
||||
cargo --version
|
||||
rustfmt --version
|
||||
cargo clippy --version
|
||||
|
||||
- name: Check formatting
|
||||
run: cargo fmt --all --check
|
||||
@@ -62,10 +59,11 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
- name: Verify runner toolchain
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
docker --version
|
||||
|
||||
- name: Install UI dependencies
|
||||
working-directory: apps/ui
|
||||
@@ -86,15 +84,12 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: 1.85.0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
- name: Verify runner toolchain
|
||||
run: |
|
||||
rustc --version
|
||||
cargo --version
|
||||
node --version
|
||||
npm --version
|
||||
|
||||
- name: Install UI dependencies
|
||||
working-directory: apps/ui
|
||||
@@ -108,22 +103,6 @@ jobs:
|
||||
working-directory: apps/ui
|
||||
run: npx playwright test
|
||||
|
||||
- name: Upload Playwright report
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-report
|
||||
path: apps/ui/playwright-report
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Upload Playwright test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-test-results
|
||||
path: apps/ui/test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
deployment:
|
||||
name: Deployment Manifests
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
@@ -1,36 +1,20 @@
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- CI
|
||||
types:
|
||||
- completed
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: deploy-${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_branch || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
env:
|
||||
IMAGE_TAG: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
|
||||
ADMIN_API_IMAGE: ghcr.io/${{ github.repository_owner }}/crank-admin-api
|
||||
MCP_SERVER_IMAGE: ghcr.io/${{ github.repository_owner }}/crank-mcp-server
|
||||
UI_IMAGE: ghcr.io/${{ github.repository_owner }}/crank-ui
|
||||
REGISTRY: git.itexp.me
|
||||
IMAGE_TAG: ${{ gitea.sha }}
|
||||
ADMIN_API_IMAGE: git.itexp.me/bsodfather/crank-community-admin-api
|
||||
MCP_SERVER_IMAGE: git.itexp.me/bsodfather/crank-community-mcp-server
|
||||
UI_IMAGE: git.itexp.me/bsodfather/crank-community-ui
|
||||
|
||||
jobs:
|
||||
build-images:
|
||||
if: >
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(
|
||||
github.event_name == 'workflow_run' &&
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
github.event.workflow_run.head_branch == 'main'
|
||||
)
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -38,82 +22,61 @@ jobs:
|
||||
include:
|
||||
- name: admin-api
|
||||
dockerfile: apps/admin-api/Dockerfile
|
||||
image: git.itexp.me/bsodfather/crank-community-admin-api
|
||||
- name: mcp-server
|
||||
dockerfile: apps/mcp-server/Dockerfile
|
||||
image: git.itexp.me/bsodfather/crank-community-mcp-server
|
||||
- name: ui
|
||||
dockerfile: apps/ui/Dockerfile
|
||||
image: git.itexp.me/bsodfather/crank-community-ui
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
|
||||
|
||||
- name: Resolve image name
|
||||
id: image
|
||||
- name: Verify runner toolchain
|
||||
run: docker --version
|
||||
|
||||
- name: Login to registry
|
||||
run: |
|
||||
case "${{ matrix.name }}" in
|
||||
admin-api) echo "name=${ADMIN_API_IMAGE}" >> "$GITHUB_OUTPUT" ;;
|
||||
mcp-server) echo "name=${MCP_SERVER_IMAGE}" >> "$GITHUB_OUTPUT" ;;
|
||||
ui) echo "name=${UI_IMAGE}" >> "$GITHUB_OUTPUT" ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
printf '%s' '${{ secrets.DEPLOY_REGISTRY_TOKEN }}' | \
|
||||
docker login '${{ env.REGISTRY }}' -u '${{ secrets.DEPLOY_REGISTRY_USER }}' --password-stdin
|
||||
|
||||
- name: Build and push ${{ matrix.name }}
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
push: true
|
||||
tags: |
|
||||
${{ steps.image.outputs.name }}:${{ env.IMAGE_TAG }}
|
||||
${{ steps.image.outputs.name }}:main
|
||||
run: |
|
||||
docker build -f '${{ matrix.dockerfile }}' \
|
||||
-t '${{ matrix.image }}:${{ env.IMAGE_TAG }}' \
|
||||
-t '${{ matrix.image }}:main' \
|
||||
.
|
||||
docker push '${{ matrix.image }}:${{ env.IMAGE_TAG }}'
|
||||
docker push '${{ matrix.image }}:main'
|
||||
|
||||
deploy:
|
||||
needs: build-images
|
||||
if: >
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(
|
||||
github.event_name == 'workflow_run' &&
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
github.event.workflow_run.head_branch == 'main'
|
||||
)
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
|
||||
|
||||
- name: Configure SSH key
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
printf '%s\n' "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519
|
||||
printf '%s\n' '${{ secrets.DEPLOY_SSH_KEY }}' > ~/.ssh/id_ed25519
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
|
||||
- name: Configure known hosts
|
||||
run: |
|
||||
printf '%s\n' "${{ secrets.DEPLOY_KNOWN_HOSTS }}" > ~/.ssh/known_hosts
|
||||
printf '%s\n' '${{ secrets.DEPLOY_KNOWN_HOSTS }}' > ~/.ssh/known_hosts
|
||||
chmod 644 ~/.ssh/known_hosts
|
||||
|
||||
- name: Sync deployment files to server
|
||||
run: |
|
||||
ssh -p "${{ secrets.DEPLOY_PORT }}" "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" \
|
||||
ssh -p '${{ secrets.DEPLOY_PORT }}' '${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}' \
|
||||
"mkdir -p '${{ secrets.DEPLOY_PATH }}'"
|
||||
rsync -az -e "ssh -p ${{ secrets.DEPLOY_PORT }}" deploy/community/docker-compose.yml \
|
||||
"${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}/docker-compose.yml"
|
||||
'${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}/docker-compose.yml'
|
||||
|
||||
- name: Write environment file
|
||||
env:
|
||||
@@ -130,6 +93,9 @@ jobs:
|
||||
CRANK_LOG_LEVEL: ${{ secrets.CRANK_LOG_LEVEL }}
|
||||
CRANK_MASTER_KEY: ${{ secrets.CRANK_MASTER_KEY }}
|
||||
CRANK_BASE_URL: ${{ secrets.CRANK_BASE_URL }}
|
||||
CRANK_CACHE_BACKEND: ${{ secrets.CRANK_CACHE_BACKEND }}
|
||||
CRANK_CACHE_URL: ${{ secrets.CRANK_CACHE_URL }}
|
||||
CRANK_CACHE_DEFAULT_TTL_MS: ${{ secrets.CRANK_CACHE_DEFAULT_TTL_MS }}
|
||||
CRANK_SESSION_SECRET: ${{ secrets.CRANK_SESSION_SECRET }}
|
||||
CRANK_PASSWORD_PEPPER: ${{ secrets.CRANK_PASSWORD_PEPPER }}
|
||||
CRANK_SESSION_TTL_HOURS: ${{ secrets.CRANK_SESSION_TTL_HOURS }}
|
||||
@@ -158,6 +124,9 @@ jobs:
|
||||
append_if_set CRANK_LOG_LEVEL "$CRANK_LOG_LEVEL"
|
||||
append_if_set CRANK_MASTER_KEY "$CRANK_MASTER_KEY"
|
||||
append_if_set CRANK_BASE_URL "$CRANK_BASE_URL"
|
||||
append_if_set CRANK_CACHE_BACKEND "$CRANK_CACHE_BACKEND"
|
||||
append_if_set CRANK_CACHE_URL "$CRANK_CACHE_URL"
|
||||
append_if_set CRANK_CACHE_DEFAULT_TTL_MS "$CRANK_CACHE_DEFAULT_TTL_MS"
|
||||
append_if_set CRANK_SESSION_SECRET "$CRANK_SESSION_SECRET"
|
||||
append_if_set CRANK_PASSWORD_PEPPER "$CRANK_PASSWORD_PEPPER"
|
||||
append_if_set CRANK_SESSION_TTL_HOURS "$CRANK_SESSION_TTL_HOURS"
|
||||
@@ -166,17 +135,17 @@ jobs:
|
||||
append_if_set CRANK_BOOTSTRAP_ADMIN_DISPLAY_NAME "$CRANK_BOOTSTRAP_ADMIN_DISPLAY_NAME"
|
||||
append_if_set CRANK_DEMO_SEED "$CRANK_DEMO_SEED"
|
||||
{
|
||||
printf 'CRANK_ADMIN_API_IMAGE=%s:%s\n' "${{ env.ADMIN_API_IMAGE }}" "${{ env.IMAGE_TAG }}"
|
||||
printf 'CRANK_MCP_SERVER_IMAGE=%s:%s\n' "${{ env.MCP_SERVER_IMAGE }}" "${{ env.IMAGE_TAG }}"
|
||||
printf 'CRANK_UI_IMAGE=%s:%s\n' "${{ env.UI_IMAGE }}" "${{ env.IMAGE_TAG }}"
|
||||
printf 'CRANK_ADMIN_API_IMAGE=%s:%s\n' '${{ env.ADMIN_API_IMAGE }}' '${{ env.IMAGE_TAG }}'
|
||||
printf 'CRANK_MCP_SERVER_IMAGE=%s:%s\n' '${{ env.MCP_SERVER_IMAGE }}' '${{ env.IMAGE_TAG }}'
|
||||
printf 'CRANK_UI_IMAGE=%s:%s\n' '${{ env.UI_IMAGE }}' '${{ env.IMAGE_TAG }}'
|
||||
} >> "$tmp_env"
|
||||
cat "$tmp_env" | ssh -p "${{ secrets.DEPLOY_PORT }}" "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" \
|
||||
cat "$tmp_env" | ssh -p '${{ secrets.DEPLOY_PORT }}' '${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}' \
|
||||
"mkdir -p '${{ secrets.DEPLOY_PATH }}' && cat > '${{ secrets.DEPLOY_PATH }}/.env'"
|
||||
rm -f "$tmp_env"
|
||||
|
||||
- name: Validate required environment variables
|
||||
run: |
|
||||
ssh -p "${{ secrets.DEPLOY_PORT }}" "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" "
|
||||
ssh -p '${{ secrets.DEPLOY_PORT }}' '${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}' "
|
||||
set -e
|
||||
cd '${{ secrets.DEPLOY_PATH }}'
|
||||
required_vars='
|
||||
@@ -203,10 +172,10 @@ jobs:
|
||||
|
||||
- name: Deploy with Docker Compose
|
||||
run: |
|
||||
ssh -p "${{ secrets.DEPLOY_PORT }}" "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" "
|
||||
ssh -p '${{ secrets.DEPLOY_PORT }}' '${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}' "
|
||||
set -e
|
||||
cd '${{ secrets.DEPLOY_PATH }}'
|
||||
echo '${{ secrets.DEPLOY_REGISTRY_TOKEN }}' | docker login ghcr.io -u '${{ secrets.DEPLOY_REGISTRY_USER }}' --password-stdin
|
||||
echo '${{ secrets.DEPLOY_REGISTRY_TOKEN }}' | docker login '${{ env.REGISTRY }}' -u '${{ secrets.DEPLOY_REGISTRY_USER }}' --password-stdin
|
||||
docker compose config -q
|
||||
docker compose pull admin-api mcp-server ui
|
||||
docker compose up -d --remove-orphans
|
||||
@@ -214,7 +183,7 @@ jobs:
|
||||
|
||||
- name: Verify health endpoints
|
||||
run: |
|
||||
ssh -p "${{ secrets.DEPLOY_PORT }}" "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" "
|
||||
ssh -p '${{ secrets.DEPLOY_PORT }}' '${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}' "
|
||||
set -e
|
||||
cd '${{ secrets.DEPLOY_PATH }}'
|
||||
for attempt in \$(seq 1 30); do
|
||||
@@ -0,0 +1,88 @@
|
||||
name: Community Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: git.itexp.me
|
||||
IMAGE_TAG: ${{ gitea.ref_name }}
|
||||
ADMIN_API_IMAGE: git.itexp.me/bsodfather/crank-community-admin-api
|
||||
MCP_SERVER_IMAGE: git.itexp.me/bsodfather/crank-community-mcp-server
|
||||
UI_IMAGE: git.itexp.me/bsodfather/crank-community-ui
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Verify runner toolchain
|
||||
run: |
|
||||
rustc --version
|
||||
cargo --version
|
||||
node --version
|
||||
npm --version
|
||||
docker --version
|
||||
|
||||
- name: Build release binaries
|
||||
run: cargo build --release -p admin-api -p mcp-server
|
||||
|
||||
- name: Install UI dependencies
|
||||
working-directory: apps/ui
|
||||
run: npm ci
|
||||
|
||||
- name: Build UI dist
|
||||
working-directory: apps/ui
|
||||
run: npm run build
|
||||
|
||||
- name: Package release artifacts
|
||||
run: |
|
||||
mkdir -p dist/release
|
||||
cp target/release/admin-api dist/release/admin-api
|
||||
cp target/release/mcp-server dist/release/mcp-server
|
||||
tar -C dist/release -czf dist/crank-community-admin-api-${IMAGE_TAG}.tar.gz admin-api
|
||||
tar -C dist/release -czf dist/crank-community-mcp-server-${IMAGE_TAG}.tar.gz mcp-server
|
||||
tar -C apps/ui/dist -czf dist/crank-community-ui-${IMAGE_TAG}.tar.gz .
|
||||
sha256sum \
|
||||
dist/crank-community-admin-api-${IMAGE_TAG}.tar.gz \
|
||||
dist/crank-community-mcp-server-${IMAGE_TAG}.tar.gz \
|
||||
dist/crank-community-ui-${IMAGE_TAG}.tar.gz \
|
||||
> dist/crank-community-${IMAGE_TAG}-checksums.txt
|
||||
|
||||
- name: Generate SBOM
|
||||
run: |
|
||||
docker run --rm -v "$PWD:/workspace" anchore/syft:latest \
|
||||
dir:/workspace -o spdx-json \
|
||||
> dist/crank-community-${IMAGE_TAG}-sbom.spdx.json
|
||||
|
||||
- name: Login to registry
|
||||
run: |
|
||||
printf '%s' '${{ secrets.DEPLOY_REGISTRY_TOKEN }}' | \
|
||||
docker login '${{ env.REGISTRY }}' -u '${{ secrets.DEPLOY_REGISTRY_USER }}' --password-stdin
|
||||
|
||||
- name: Build and push release images
|
||||
run: |
|
||||
docker build -f apps/admin-api/Dockerfile \
|
||||
-t '${{ env.ADMIN_API_IMAGE }}:${{ env.IMAGE_TAG }}' \
|
||||
-t '${{ env.ADMIN_API_IMAGE }}:latest' .
|
||||
docker build -f apps/mcp-server/Dockerfile \
|
||||
-t '${{ env.MCP_SERVER_IMAGE }}:${{ env.IMAGE_TAG }}' \
|
||||
-t '${{ env.MCP_SERVER_IMAGE }}:latest' .
|
||||
docker build -f apps/ui/Dockerfile \
|
||||
-t '${{ env.UI_IMAGE }}:${{ env.IMAGE_TAG }}' \
|
||||
-t '${{ env.UI_IMAGE }}:latest' .
|
||||
docker push '${{ env.ADMIN_API_IMAGE }}:${{ env.IMAGE_TAG }}'
|
||||
docker push '${{ env.ADMIN_API_IMAGE }}:latest'
|
||||
docker push '${{ env.MCP_SERVER_IMAGE }}:${{ env.IMAGE_TAG }}'
|
||||
docker push '${{ env.MCP_SERVER_IMAGE }}:latest'
|
||||
docker push '${{ env.UI_IMAGE }}:${{ env.IMAGE_TAG }}'
|
||||
docker push '${{ env.UI_IMAGE }}:latest'
|
||||
|
||||
- name: Show release bundle summary
|
||||
run: |
|
||||
ls -lh dist
|
||||
@@ -1,144 +0,0 @@
|
||||
name: Community Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
env:
|
||||
IMAGE_TAG: ${{ github.ref_name }}
|
||||
ADMIN_API_IMAGE: ghcr.io/${{ github.repository_owner }}/crank-community-admin-api
|
||||
MCP_SERVER_IMAGE: ghcr.io/${{ github.repository_owner }}/crank-community-mcp-server
|
||||
UI_IMAGE: ghcr.io/${{ github.repository_owner }}/crank-community-ui
|
||||
|
||||
jobs:
|
||||
build-release-assets:
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: 1.85.0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Build release binaries
|
||||
run: cargo build --release -p admin-api -p mcp-server
|
||||
|
||||
- name: Install UI dependencies
|
||||
working-directory: apps/ui
|
||||
run: npm ci
|
||||
|
||||
- name: Build UI dist
|
||||
working-directory: apps/ui
|
||||
run: npm run build
|
||||
|
||||
- name: Package release artifacts
|
||||
run: |
|
||||
mkdir -p dist/release
|
||||
cp target/release/admin-api dist/release/admin-api
|
||||
cp target/release/mcp-server dist/release/mcp-server
|
||||
tar -C dist/release -czf dist/crank-community-admin-api-${IMAGE_TAG}.tar.gz admin-api
|
||||
tar -C dist/release -czf dist/crank-community-mcp-server-${IMAGE_TAG}.tar.gz mcp-server
|
||||
tar -C apps/ui/dist -czf dist/crank-community-ui-${IMAGE_TAG}.tar.gz .
|
||||
sha256sum \
|
||||
dist/crank-community-admin-api-${IMAGE_TAG}.tar.gz \
|
||||
dist/crank-community-mcp-server-${IMAGE_TAG}.tar.gz \
|
||||
dist/crank-community-ui-${IMAGE_TAG}.tar.gz \
|
||||
> dist/crank-community-${IMAGE_TAG}-checksums.txt
|
||||
|
||||
- name: Generate SBOM
|
||||
run: |
|
||||
docker run --rm -v "$PWD:/workspace" anchore/syft:latest \
|
||||
dir:/workspace -o spdx-json \
|
||||
> dist/crank-community-${IMAGE_TAG}-sbom.spdx.json
|
||||
|
||||
- name: Upload release artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: community-release-artifacts
|
||||
path: |
|
||||
dist/crank-community-admin-api-${{ env.IMAGE_TAG }}.tar.gz
|
||||
dist/crank-community-mcp-server-${{ env.IMAGE_TAG }}.tar.gz
|
||||
dist/crank-community-ui-${{ env.IMAGE_TAG }}.tar.gz
|
||||
dist/crank-community-${{ env.IMAGE_TAG }}-checksums.txt
|
||||
dist/crank-community-${{ env.IMAGE_TAG }}-sbom.spdx.json
|
||||
|
||||
publish-images:
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: admin-api
|
||||
dockerfile: apps/admin-api/Dockerfile
|
||||
image: ghcr.io/${{ github.repository_owner }}/crank-community-admin-api
|
||||
- name: mcp-server
|
||||
dockerfile: apps/mcp-server/Dockerfile
|
||||
image: ghcr.io/${{ github.repository_owner }}/crank-community-mcp-server
|
||||
- name: ui
|
||||
dockerfile: apps/ui/Dockerfile
|
||||
image: ghcr.io/${{ github.repository_owner }}/crank-community-ui
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push ${{ matrix.name }}
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
push: true
|
||||
tags: |
|
||||
${{ matrix.image }}:${{ env.IMAGE_TAG }}
|
||||
${{ matrix.image }}:latest
|
||||
|
||||
github-release:
|
||||
needs:
|
||||
- build-release-assets
|
||||
- publish-images
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
|
||||
steps:
|
||||
- name: Download release artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: community-release-artifacts
|
||||
path: dist
|
||||
|
||||
- name: Publish GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
dist/crank-community-admin-api-${{ env.IMAGE_TAG }}.tar.gz
|
||||
dist/crank-community-mcp-server-${{ env.IMAGE_TAG }}.tar.gz
|
||||
dist/crank-community-ui-${{ env.IMAGE_TAG }}.tar.gz
|
||||
dist/crank-community-${{ env.IMAGE_TAG }}-checksums.txt
|
||||
dist/crank-community-${{ env.IMAGE_TAG }}-sbom.spdx.json
|
||||
@@ -93,13 +93,15 @@ Crank - платформа для публикации внешних API в в
|
||||
В репозитории настроены:
|
||||
|
||||
- `CI` для Rust, UI и deployment manifests;
|
||||
- `CD`, который после успешного `CI` на `main` собирает versioned images, пушит их в `GHCR` и деплоит Community через `deploy/community/docker-compose.yml`;
|
||||
- `CD`, который на `push` в `main` собирает versioned images, пушит их в registry Gitea и деплоит Community через `deploy/community/docker-compose.yml`;
|
||||
- tag-based release workflow для сборки release bundle и versioned images;
|
||||
- containerized Community deployment через `deploy/community/docker-compose.yml`.
|
||||
|
||||
Важно:
|
||||
|
||||
- GitHub Actions в этом репозитории рассчитаны только на `self-hosted` runner;
|
||||
- `ubuntu-latest`, `actions/cache` и `type=gha` intentionally не используются, чтобы не тратить платные GitHub-hosted минуты и cache quota на private repository.
|
||||
- workflows лежат в `.gitea/workflows`;
|
||||
- Gitea Actions в этом репозитории рассчитаны только на `self-hosted` runner;
|
||||
- внешние GitHub-specific механики вроде `workflow_run`, `actions/upload-artifact`, `softprops/action-gh-release` и `ghcr.io` intentionally не используются.
|
||||
|
||||
## Поддерживаемые протоколы
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
- `deploy/community/docker-compose.yml`
|
||||
- `deploy/community/.env.example`
|
||||
- `.github/workflows/ci.yml`
|
||||
- `.github/workflows/deploy.yml`
|
||||
- `.gitea/workflows/ci.yml`
|
||||
- `.gitea/workflows/deploy.yml`
|
||||
- `docs/deployment.md`
|
||||
- `docs/deploy-and-staging-smoke.md`
|
||||
- `docs/authenticated-staging-pass.md`
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
- задеплоенный стек `ui`, `admin-api`, `mcp-server`, `postgres`;
|
||||
- корректный `.env` на сервере;
|
||||
- валидный deploy через `.github/workflows/deploy.yml`;
|
||||
- валидный deploy через `.gitea/workflows/deploy.yml`;
|
||||
- server deployment path, собранный из `deploy/community/docker-compose.yml`;
|
||||
- `CRANK_DEMO_SEED=true`, если нужен предзаполненный smoke state;
|
||||
- bootstrap admin credentials для входа в UI.
|
||||
|
||||
+5
-5
@@ -38,8 +38,8 @@
|
||||
- `deploy/community/docker-compose.yml` как canonical Community deployment manifest;
|
||||
- `deploy/community/.env.example` как canonical Community runtime env template;
|
||||
- `docker-compose.yml` и root `.env.example` только как local development convenience layers, а не как future private delivery boundary;
|
||||
- `.github/workflows/ci.yml`;
|
||||
- `.github/workflows/deploy.yml`;
|
||||
- `.gitea/workflows/ci.yml`;
|
||||
- `.gitea/workflows/deploy.yml`;
|
||||
- примеры reverse proxy конфигураций.
|
||||
|
||||
Рекомендуемое стартовое распределение портов:
|
||||
@@ -236,9 +236,9 @@ CD для MVP должен:
|
||||
|
||||
Для текущего проекта базовая рекомендуемая схема:
|
||||
|
||||
- `GHCR` как registry;
|
||||
- registry на том же Gitea instance;
|
||||
- versioned tags по `git sha`;
|
||||
- `docker/buildx` cache в GitHub Actions;
|
||||
- self-hosted Gitea Actions runner;
|
||||
- на сервере только `pull + restart`, без `docker compose up --build`.
|
||||
|
||||
Для private registry на сервере нужны отдельные deployment secrets:
|
||||
@@ -251,7 +251,7 @@ CD для MVP должен:
|
||||
Монолитный `DEPLOY_ENV_FILE` больше не используется.
|
||||
|
||||
Workflow доставляет именно `deploy/community/docker-compose.yml` как public Community deployment manifest
|
||||
и собирает `.env` на сервере из отдельных GitHub secrets. Для runtime-переменных нужно
|
||||
и собирает `.env` на сервере из отдельных Gitea secrets. Для runtime-переменных нужно
|
||||
создавать secrets с теми же именами, что и у приложений:
|
||||
|
||||
- `POSTGRES_HOST`
|
||||
|
||||
@@ -1570,22 +1570,22 @@
|
||||
|
||||
<task id="6.1" parallel="false" location="crank-community">
|
||||
<name>Community release pipeline</name>
|
||||
<create path=".github/workflows/release.yml">
|
||||
<create path=".gitea/workflows/release.yml">
|
||||
Trigger: push tag v*.
|
||||
Steps: build admin-api, mcp-server, UI dist; build Docker images; push to ghcr.io/<owner>/crank-community-{admin-api,mcp-server}; attach checksums + SBOM; create GitHub Release.
|
||||
Steps: build admin-api, mcp-server, UI dist; build Docker images; push to the Gitea container registry; assemble checksums + SBOM on the self-hosted runner.
|
||||
</create>
|
||||
</task>
|
||||
|
||||
<task id="6.2" parallel="false" location="crank-enterprise">
|
||||
<name>Enterprise release pipeline</name>
|
||||
<create path=".github/workflows/release.yml">
|
||||
<create path=".gitea/workflows/release.yml">
|
||||
Push tag v* triggers: fetch submodule at the pinned community tag; build enterprise-admin-api / enterprise-mcp-server / enterprise-ui-overlay; build Docker images; push to private registry; sign with cosign; produce SBOM.
|
||||
</create>
|
||||
</task>
|
||||
|
||||
<task id="6.3" parallel="false" location="crank-cloud">
|
||||
<name>Cloud release pipeline + control-plane rollout</name>
|
||||
<create path=".github/workflows/release.yml">
|
||||
<create path=".gitea/workflows/release.yml">
|
||||
Build cloud-admin-api / cloud-mcp-server / cloud-control-plane; push to managed registry; trigger blue/green rollout in hosted environment.
|
||||
</create>
|
||||
</task>
|
||||
|
||||
@@ -150,7 +150,7 @@ Demo/deployment:
|
||||
- стабильный `Streamable HTTP` endpoint для MCP.
|
||||
- containerized runtime через `Docker` и `docker-compose`.
|
||||
- optional shared cache layer через `Valkey/Redis`.
|
||||
- registry-backed image rollout через `GHCR` или совместимый registry.
|
||||
- registry-backed image rollout через Gitea Container Registry или совместимый registry.
|
||||
|
||||
### Cache env
|
||||
|
||||
|
||||
Reference in New Issue
Block a user