Files
mcpctl/.gitea/workflows/ci.yml
Michal adb8b42938
Some checks failed
CI/CD / lint (push) Successful in 41s
CI/CD / typecheck (push) Successful in 42s
CI/CD / test (push) Successful in 53s
CI/CD / build (push) Successful in 1m8s
CI/CD / docker (push) Failing after 33s
CI/CD / publish-rpm (push) Successful in 38s
CI/CD / deploy (push) Has been skipped
ci: switch docker job from docker CLI to podman
Docker CLI can't connect to the podman socket in the runner container
(permission denied even as root). Switch to podman for building images
locally and skopeo with containers-storage transport for pushing.
Podman builds don't need a daemon socket.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:58:57 +00:00

275 lines
8.7 KiB
YAML

name: CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
GITEA_REGISTRY: 10.0.0.194:3012
GITEA_OWNER: michal
# ============================================================
# Required Gitea secrets:
# PACKAGES_TOKEN — Gitea API token (packages + registry)
# PORTAINER_PASSWORD — Portainer login for stack deploy
# POSTGRES_PASSWORD — Database password for production stack
# ============================================================
jobs:
# ── CI checks (run in parallel on every push/PR) ──────────
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint || echo "::warning::Lint has errors — not blocking CI yet"
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Generate Prisma client
run: pnpm --filter @mcpctl/db exec prisma generate
- name: Typecheck
run: pnpm typecheck
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Generate Prisma client
run: pnpm --filter @mcpctl/db exec prisma generate
- name: Build (needed by completions test)
run: pnpm build
- name: Run tests
run: pnpm test:run
# ── Build & package RPM ───────────────────────────────────
build:
runs-on: ubuntu-latest
needs: [lint, typecheck, test]
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- name: Install dependencies (hoisted for bun compile compatibility)
run: |
echo "node-linker=hoisted" >> .npmrc
pnpm install --frozen-lockfile
- name: Generate Prisma client
run: pnpm --filter @mcpctl/db exec prisma generate
- name: Build all packages
run: pnpm build
- name: Generate shell completions
run: pnpm completions:generate
- uses: oven-sh/setup-bun@v2
- name: Install nfpm
run: |
curl -sL -o /tmp/nfpm.tar.gz "https://github.com/goreleaser/nfpm/releases/download/v2.45.0/nfpm_2.45.0_Linux_x86_64.tar.gz"
tar xzf /tmp/nfpm.tar.gz -C /usr/local/bin nfpm
- name: Bundle standalone binaries
run: |
mkdir -p dist
# Stub for optional dep that Ink tries to import (only used when DEV=true)
# Copy instead of symlink — bun can't read directory symlinks
if [ ! -e node_modules/react-devtools-core/package.json ]; then
rm -rf node_modules/react-devtools-core
cp -r src/cli/stubs/react-devtools-core node_modules/react-devtools-core
fi
bun build src/cli/src/index.ts --compile --outfile dist/mcpctl
bun build src/mcplocal/src/main.ts --compile --outfile dist/mcpctl-local
- name: Package RPM
run: nfpm pkg --packager rpm --target dist/
- name: Upload RPM artifact
uses: actions/upload-artifact@v3
with:
name: rpm-package
path: dist/mcpctl-*.rpm
retention-days: 7
# ── Release pipeline (main branch push only) ──────────────
docker:
runs-on: ubuntu-latest
needs: [build]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
env:
REGISTRY: ${{ env.GITEA_REGISTRY }}
OWNER: ${{ env.GITEA_OWNER }}
steps:
- uses: actions/checkout@v4
- name: Install podman and skopeo
run: sudo apt-get update && sudo apt-get install -y podman skopeo
- name: Build & push mcpd
run: |
sudo -E podman build -t mcpd:latest -f deploy/Dockerfile.mcpd .
sudo -E skopeo copy --dest-tls-verify=false \
--dest-creds "${{ env.OWNER }}:${{ secrets.PACKAGES_TOKEN }}" \
containers-storage:mcpd:latest \
docker://${{ env.REGISTRY }}/${{ env.OWNER }}/mcpd:latest
- name: Build & push node-runner
run: |
sudo -E podman build -t node-runner:latest -f deploy/Dockerfile.node-runner .
sudo -E skopeo copy --dest-tls-verify=false \
--dest-creds "${{ env.OWNER }}:${{ secrets.PACKAGES_TOKEN }}" \
containers-storage:node-runner:latest \
docker://${{ env.REGISTRY }}/${{ env.OWNER }}/mcpctl-node-runner:latest
- name: Build & push python-runner
run: |
sudo -E podman build -t python-runner:latest -f deploy/Dockerfile.python-runner .
sudo -E skopeo copy --dest-tls-verify=false \
--dest-creds "${{ env.OWNER }}:${{ secrets.PACKAGES_TOKEN }}" \
containers-storage:python-runner:latest \
docker://${{ env.REGISTRY }}/${{ env.OWNER }}/mcpctl-python-runner:latest
- name: Build & push docmost-mcp
run: |
sudo -E podman build -t docmost-mcp:latest -f deploy/Dockerfile.docmost-mcp .
sudo -E skopeo copy --dest-tls-verify=false \
--dest-creds "${{ env.OWNER }}:${{ secrets.PACKAGES_TOKEN }}" \
containers-storage:docmost-mcp:latest \
docker://${{ env.REGISTRY }}/${{ env.OWNER }}/docmost-mcp:latest
- name: Link packages to repository
env:
GITEA_TOKEN: ${{ secrets.PACKAGES_TOKEN }}
GITEA_URL: http://${{ env.GITEA_REGISTRY }}
GITEA_OWNER: ${{ env.GITEA_OWNER }}
GITEA_REPO: mcpctl
run: |
source scripts/link-package.sh
link_package "container" "mcpd"
link_package "container" "mcpctl-node-runner"
link_package "container" "mcpctl-python-runner"
link_package "container" "docmost-mcp"
publish-rpm:
runs-on: ubuntu-latest
needs: [build]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- name: Download RPM artifact
uses: actions/download-artifact@v3
with:
name: rpm-package
path: dist/
- name: Install rpm tools
run: sudo apt-get update && sudo apt-get install -y rpm
- name: Publish RPM to Gitea
env:
GITEA_TOKEN: ${{ secrets.PACKAGES_TOKEN }}
GITEA_URL: http://${{ env.GITEA_REGISTRY }}
GITEA_OWNER: ${{ env.GITEA_OWNER }}
GITEA_REPO: mcpctl
run: |
RPM_FILE=$(ls dist/mcpctl-*.rpm | head -1)
RPM_VERSION=$(rpm -qp --queryformat '%{VERSION}-%{RELEASE}' "$RPM_FILE")
echo "Publishing $RPM_FILE (version $RPM_VERSION)..."
# Delete existing version if present
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL}/api/v1/packages/${GITEA_OWNER}/rpm/mcpctl/${RPM_VERSION}")
if [ "$HTTP_CODE" = "200" ]; then
echo "Version exists, replacing..."
curl -s -o /dev/null -X DELETE \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL}/api/v1/packages/${GITEA_OWNER}/rpm/mcpctl/${RPM_VERSION}"
fi
# Upload
curl --fail -X PUT \
-H "Authorization: token ${GITEA_TOKEN}" \
--upload-file "$RPM_FILE" \
"${GITEA_URL}/api/packages/${GITEA_OWNER}/rpm/upload"
echo "Published successfully!"
# Link package to repo
source scripts/link-package.sh
link_package "rpm" "mcpctl"
deploy:
runs-on: ubuntu-latest
needs: [docker, publish-rpm]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- name: Create stack env file
env:
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
run: |
printf '%s\n' \
"POSTGRES_USER=mcpctl" \
"POSTGRES_PASSWORD=${POSTGRES_PASSWORD}" \
"POSTGRES_DB=mcpctl" \
"MCPD_PORT=3100" \
"MCPD_LOG_LEVEL=info" \
> stack/.env
- name: Deploy to Portainer
env:
PORTAINER_PASSWORD: ${{ secrets.PORTAINER_PASSWORD }}
run: bash deploy.sh