From 088fc2db65bd0e9287f8e63769e5c2fd0f9264c5 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 4 Jul 2026 01:29:16 -0400 Subject: [PATCH] fix build --- .gitea/workflows/build-and-deploy.yml | 148 ++++++++++++++------------ 1 file changed, 79 insertions(+), 69 deletions(-) diff --git a/.gitea/workflows/build-and-deploy.yml b/.gitea/workflows/build-and-deploy.yml index e80d16d..29ab64f 100644 --- a/.gitea/workflows/build-and-deploy.yml +++ b/.gitea/workflows/build-and-deploy.yml @@ -23,26 +23,21 @@ jobs: build-image: name: Build & Push Docker Image runs-on: ubuntu-latest - container: - image: docker:27-git - defaults: - run: - shell: sh outputs: image_repository: ${{ steps.image-meta.outputs.repository }} docker_image: ${{ steps.image-meta.outputs.full }} steps: - name: Checkout repository - shell: sh + shell: bash env: GITEA_SERVER_URL: ${{ gitea.server_url }} GITEA_REPOSITORY: ${{ gitea.repository }} GITEA_SHA: ${{ gitea.sha }} CHECKOUT_TOKEN: ${{ gitea.token }} run: | - set -eu + set -euo pipefail if ! command -v git >/dev/null 2>&1; then - echo "::error::git is not available in the job image. Use a runner image that includes git, such as docker:27-git." + echo "::error::git must be available in the runner image; this workflow cannot install git while runner DNS is unavailable." exit 1 fi @@ -72,35 +67,6 @@ jobs: fi git checkout --force FETCH_HEAD - - name: Ensure Docker CLI is available - run: | - if ! command -v docker >/dev/null 2>&1; then - echo "::error::docker is not available in the job image. Use a runner image that includes Docker CLI and Buildx." - exit 1 - fi - docker --version - docker info >/dev/null - - - name: Set up Docker Buildx - run: | - if ! docker buildx version >/dev/null 2>&1; then - echo "::error::Docker Buildx is not available on this runner" - exit 1 - fi - - cat > /tmp/buildkitd.toml <<'EOF' - [registry."192.168.3.80"] - insecure = true - EOF - - docker buildx rm gitea-builder >/dev/null 2>&1 || true - docker buildx create \ - --name gitea-builder \ - --driver docker-container \ - --use \ - --buildkitd-config /tmp/buildkitd.toml - docker buildx inspect --bootstrap - - name: Docker image metadata id: image-meta run: | @@ -121,7 +87,7 @@ jobs: fi - name: Validate public URLs - shell: sh + shell: bash env: NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }} NEXT_PUBLIC_HOMEPAGE_URL: ${{ secrets.NEXT_PUBLIC_HOMEPAGE_URL }} @@ -153,50 +119,94 @@ jobs: validate_url NEXT_PUBLIC_ADMIN_URL "$NEXT_PUBLIC_ADMIN_URL" validate_url SITE_ORIGIN "$SITE_ORIGIN" - - name: Log in to Gitea Container Registry - if: steps.registry-check.outputs.available == 'true' - env: - REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} - REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} + - name: Check remote build credentials + id: check-build-host run: | - printf '%s' "$REGISTRY_PASSWORD" | docker login "$REGISTRY_HOST" \ - --username "$REGISTRY_USERNAME" \ - --password-stdin + if [ -z "${{ secrets.VPS_SSH_KEY }}" ] || \ + [ -z "${{ secrets.VPS_IP }}" ] || \ + [ -z "${{ secrets.VPS_USER }}" ]; then + echo "::error::VPS_SSH_KEY, VPS_IP, and VPS_USER are required to build on the remote Docker host" + exit 1 + fi - - name: Build and push + - name: Check SSH tools + run: | + if ! command -v ssh >/dev/null 2>&1 || ! command -v tar >/dev/null 2>&1; then + echo "::error::ssh and tar must be available in the runner image; this workflow cannot install packages while runner DNS is unavailable." + exit 1 + fi + + - name: Set up SSH key + run: | + mkdir -p ~/.ssh && chmod 700 ~/.ssh + echo "${{ secrets.VPS_SSH_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H "${{ secrets.VPS_IP }}" >> ~/.ssh/known_hosts 2>/dev/null + chmod 644 ~/.ssh/known_hosts + + - name: Sync build context to VPS + env: + REMOTE_BUILD_DIR: ${{ env.DEPLOY_ROOT }}/build-context + run: | + ssh "${{ secrets.VPS_USER }}@${{ secrets.VPS_IP }}" \ + "rm -rf '$REMOTE_BUILD_DIR' && mkdir -p '$REMOTE_BUILD_DIR'" + tar \ + --exclude='.git' \ + --exclude='node_modules' \ + --exclude='.next' \ + --exclude='dist' \ + --exclude='coverage' \ + -czf - . | ssh "${{ secrets.VPS_USER }}@${{ secrets.VPS_IP }}" \ + "tar -xzf - -C '$REMOTE_BUILD_DIR'" + + - name: Build and push on VPS env: - BUILDKIT_NO_CLIENT_TOKEN: "true" PUSH_IMAGE: ${{ steps.registry-check.outputs.available == 'true' }} IMAGE_FULL: ${{ steps.image-meta.outputs.full }} IMAGE_LATEST: ${{ steps.image-meta.outputs.latest }} + REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }} NEXT_PUBLIC_HOMEPAGE_URL: ${{ secrets.NEXT_PUBLIC_HOMEPAGE_URL }} NEXT_PUBLIC_STOREFRONT_URL: ${{ secrets.NEXT_PUBLIC_STOREFRONT_URL }} NEXT_PUBLIC_DASHBOARD_URL: ${{ secrets.NEXT_PUBLIC_DASHBOARD_URL }} NEXT_PUBLIC_ADMIN_URL: ${{ secrets.NEXT_PUBLIC_ADMIN_URL }} SITE_ORIGIN: ${{ secrets.SITE_ORIGIN }} + REMOTE_BUILD_DIR: ${{ env.DEPLOY_ROOT }}/build-context run: | - output_flag="--load" - if [ "$PUSH_IMAGE" = "true" ]; then - output_flag="--push" - fi - - docker buildx build \ - --file "$DOCKERFILE_PATH" \ - --platform "$DOCKER_PLATFORM" \ - --tag "$IMAGE_FULL" \ - --tag "$IMAGE_LATEST" \ - --build-arg API_INTERNAL_URL=http://api:4000/api/v1 \ - --build-arg DASHBOARD_INTERNAL_URL=http://dashboard:3001 \ - --build-arg ADMIN_INTERNAL_URL=http://admin:3002 \ - --build-arg NEXT_PUBLIC_API_URL="$NEXT_PUBLIC_API_URL" \ - --build-arg NEXT_PUBLIC_HOMEPAGE_URL="$NEXT_PUBLIC_HOMEPAGE_URL" \ - --build-arg NEXT_PUBLIC_STOREFRONT_URL="$NEXT_PUBLIC_STOREFRONT_URL" \ - --build-arg NEXT_PUBLIC_DASHBOARD_URL="$NEXT_PUBLIC_DASHBOARD_URL" \ - --build-arg NEXT_PUBLIC_ADMIN_URL="$NEXT_PUBLIC_ADMIN_URL" \ - --build-arg SITE_ORIGIN="$SITE_ORIGIN" \ - "$output_flag" \ - . + REGISTRY_PASSWORD_B64="$(printf '%s' "$REGISTRY_PASSWORD" | base64 | tr -d '\n')" + ssh "${{ secrets.VPS_USER }}@${{ secrets.VPS_IP }}" " + set -e + cd '$REMOTE_BUILD_DIR' + if ! command -v docker >/dev/null 2>&1; then + echo 'Docker must be installed on the VPS build host' >&2 + exit 1 + fi + if [ '$PUSH_IMAGE' = 'true' ]; then + printf '%s' '$REGISTRY_PASSWORD_B64' | base64 -d | docker login '$REGISTRY_HOST' \ + --username '$REGISTRY_USERNAME' \ + --password-stdin + fi + docker build \ + --file '$DOCKERFILE_PATH' \ + --platform '$DOCKER_PLATFORM' \ + --tag '$IMAGE_FULL' \ + --tag '$IMAGE_LATEST' \ + --build-arg API_INTERNAL_URL=http://api:4000/api/v1 \ + --build-arg DASHBOARD_INTERNAL_URL=http://dashboard:3001 \ + --build-arg ADMIN_INTERNAL_URL=http://admin:3002 \ + --build-arg NEXT_PUBLIC_API_URL='$NEXT_PUBLIC_API_URL' \ + --build-arg NEXT_PUBLIC_HOMEPAGE_URL='$NEXT_PUBLIC_HOMEPAGE_URL' \ + --build-arg NEXT_PUBLIC_STOREFRONT_URL='$NEXT_PUBLIC_STOREFRONT_URL' \ + --build-arg NEXT_PUBLIC_DASHBOARD_URL='$NEXT_PUBLIC_DASHBOARD_URL' \ + --build-arg NEXT_PUBLIC_ADMIN_URL='$NEXT_PUBLIC_ADMIN_URL' \ + --build-arg SITE_ORIGIN='$SITE_ORIGIN' \ + . + if [ '$PUSH_IMAGE' = 'true' ]; then + docker push '$IMAGE_FULL' + docker push '$IMAGE_LATEST' + fi + " deploy: name: Deploy to VPS