Download server/tasks/pipeline_build_deploy.py from jester1177/cloudnative-devops-debug-env: direct link, hf CLI and curl.
- Browser
- Download file 15.8 kB
-
https://huggingface.co/spaces/jester1177/cloudnative-devops-debug-env/resolve/main/server/tasks/pipeline_build_deploy.py
- Command line
-
hf download hf://spaces/jester1177/cloudnative-devops-debug-env/server/tasks/pipeline_build_deploy.py
-
curl -L -o pipeline_build_deploy.py https://huggingface.co/spaces/jester1177/cloudnative-devops-debug-env/resolve/main/server/tasks/pipeline_build_deploy.py
15.8 kB
| """Task: CI/CD Build & Push Pipeline — HARD. | |
| Agent debugs combined GHA + Docker + Registry pipeline failures: | |
| GHCR login missing token, wrong image tag in workflow, missing permissions, | |
| Dockerfile + workflow arg mismatch, multi-stage build output mismatch. | |
| """ | |
| from server.models import TaskDifficulty | |
| from server.tasks.base import BaseTask | |
| class PipelineBuildDeployTask(BaseTask): | |
| NAME = "CI/CD Build & Push Pipeline" | |
| DESCRIPTION = "Debug GHA-to-Docker-to-Registry pipeline failures across multiple files" | |
| DIFFICULTY = TaskDifficulty.HARD | |
| AVAILABLE_SECRETS = ["GITHUB_TOKEN", "DOCKER_USERNAME", "DOCKER_PASSWORD"] | |
| SCENARIOS = [ | |
| # Scenario 1: Registry mismatch — build tags ghcr.io but push targets docker.io | |
| { | |
| "id": "registry_mismatch", | |
| "files": [ | |
| { | |
| "path": ".github/workflows/deploy.yml", | |
| "type": "workflow", | |
| "content": ( | |
| "name: Build and Push\n" | |
| "on:\n" | |
| " push:\n" | |
| " branches: [main]\n" | |
| "\n" | |
| "jobs:\n" | |
| " build:\n" | |
| " runs-on: ubuntu-latest\n" | |
| " permissions:\n" | |
| " packages: write\n" | |
| " steps:\n" | |
| " - uses: actions/checkout@v4\n" | |
| "\n" | |
| " - name: Login to GHCR\n" | |
| " run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin\n" | |
| "\n" | |
| " - name: Build image\n" | |
| " run: docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .\n" | |
| "\n" | |
| " - name: Push image\n" | |
| " run: docker push docker.io/${{ github.repository }}:${{ github.sha }}\n" | |
| ), | |
| }, | |
| { | |
| "path": "Dockerfile", | |
| "type": "dockerfile", | |
| "content": ( | |
| "FROM node:20-alpine\n" | |
| "WORKDIR /app\n" | |
| "COPY package*.json ./\n" | |
| "RUN npm ci\n" | |
| "COPY . .\n" | |
| "EXPOSE 3000\n" | |
| 'CMD ["npm", "start"]\n' | |
| ), | |
| }, | |
| { | |
| "path": "package.json", | |
| "type": "other", | |
| "content": '{"name": "myapp", "scripts": {"start": "node server.js"}}', | |
| }, | |
| ], | |
| "error": { | |
| "phase": "pipeline_build", | |
| "message": ( | |
| "Run: Build and Push\n" | |
| "\n" | |
| "Step: Build image ✓\n" | |
| "Step: Push image ✗\n" | |
| "Error: An image does not exist locally with the tag: docker.io/<repo>:<sha>\n" | |
| "\n" | |
| "The image was built with a ghcr.io tag but the push targets docker.io." | |
| ), | |
| "exit_code": 1, | |
| "failed_step": "Push image", | |
| }, | |
| "expected_fixes": [ | |
| { | |
| "file": ".github/workflows/deploy.yml", | |
| "type": "contains", | |
| "expected": "docker push ghcr.io/", | |
| "hint": "The push command targets docker.io but the image was tagged with ghcr.io — use the same registry", | |
| } | |
| ], | |
| }, | |
| # Scenario 2: Image tag mismatch between build and push steps | |
| { | |
| "id": "image_tag_mismatch", | |
| "files": [ | |
| { | |
| "path": ".github/workflows/build.yml", | |
| "type": "workflow", | |
| "content": ( | |
| "name: Build and Push\n" | |
| "on:\n" | |
| " push:\n" | |
| " tags: ['v*']\n" | |
| "\n" | |
| "jobs:\n" | |
| " build:\n" | |
| " runs-on: ubuntu-latest\n" | |
| " steps:\n" | |
| " - uses: actions/checkout@v4\n" | |
| "\n" | |
| " - name: Login to DockerHub\n" | |
| " run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin\n" | |
| "\n" | |
| " - name: Build image\n" | |
| " run: docker build -t myuser/myapp:${{ github.ref_name }} .\n" | |
| "\n" | |
| " - name: Push image\n" | |
| " run: docker push myuser/myapp:${{ github.sha }}\n" | |
| ), | |
| }, | |
| { | |
| "path": "Dockerfile", | |
| "type": "dockerfile", | |
| "content": ( | |
| "FROM python:3.11-slim\n" | |
| "WORKDIR /app\n" | |
| "COPY requirements.txt .\n" | |
| "RUN pip install -r requirements.txt\n" | |
| "COPY . .\n" | |
| "EXPOSE 7860\n" | |
| 'CMD ["python", "app.py"]\n' | |
| ), | |
| }, | |
| { | |
| "path": "requirements.txt", | |
| "type": "requirements", | |
| "content": "flask==3.0.0\ngunicorn==21.2.0\n", | |
| }, | |
| ], | |
| "error": { | |
| "phase": "pipeline_build", | |
| "message": ( | |
| "Run: Build and Push\n" | |
| "\n" | |
| "Step: Build image ✓\n" | |
| "Step: Push image ✗\n" | |
| "Error: An image does not exist locally with the tag: myuser/myapp:<sha>\n" | |
| "\n" | |
| "The build used github.ref_name as the tag but push used github.sha. " | |
| "These are different values." | |
| ), | |
| "exit_code": 1, | |
| "failed_step": "Push image", | |
| }, | |
| "expected_fixes": [ | |
| { | |
| "file": ".github/workflows/build.yml", | |
| "type": "contains", | |
| "expected": "docker push myuser/myapp:${{ github.ref_name }}", | |
| "hint": "Build tags image with github.ref_name but push uses github.sha — use the same tag", | |
| } | |
| ], | |
| }, | |
| # Scenario 3: Build and push use different tagging strategies (sha vs latest) | |
| { | |
| "id": "inconsistent_tagging", | |
| "files": [ | |
| { | |
| "path": ".github/workflows/publish.yml", | |
| "type": "workflow", | |
| "content": ( | |
| "name: Publish\n" | |
| "on:\n" | |
| " push:\n" | |
| " branches: [main]\n" | |
| "\n" | |
| "jobs:\n" | |
| " publish:\n" | |
| " runs-on: ubuntu-latest\n" | |
| " steps:\n" | |
| " - uses: actions/checkout@v4\n" | |
| "\n" | |
| " - name: Login to DockerHub\n" | |
| " run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin\n" | |
| "\n" | |
| " - name: Build\n" | |
| " run: docker build -t myuser/api:${{ github.sha }} .\n" | |
| "\n" | |
| " - name: Test\n" | |
| " run: docker run myuser/api:${{ github.sha }} python -m pytest\n" | |
| "\n" | |
| " - name: Tag latest\n" | |
| " run: docker tag myuser/api:latest myuser/api:stable\n" | |
| "\n" | |
| " - name: Push\n" | |
| " run: |\n" | |
| " docker push myuser/api:${{ github.sha }}\n" | |
| " docker push myuser/api:stable\n" | |
| ), | |
| }, | |
| { | |
| "path": "Dockerfile", | |
| "type": "dockerfile", | |
| "content": ( | |
| "FROM python:3.11-slim\n" | |
| "WORKDIR /app\n" | |
| "COPY requirements.txt .\n" | |
| "RUN pip install -r requirements.txt\n" | |
| "COPY . .\n" | |
| 'CMD ["python", "app.py"]\n' | |
| ), | |
| }, | |
| { | |
| "path": "requirements.txt", | |
| "type": "requirements", | |
| "content": "flask==3.0.0\npytest==7.4.0\n", | |
| }, | |
| ], | |
| "error": { | |
| "phase": "pipeline_build", | |
| "message": ( | |
| "Run: Publish\n" | |
| "\n" | |
| "Step: Build ✓ (myuser/api:<sha>)\n" | |
| "Step: Test ✓\n" | |
| "Step: Tag latest ✗\n" | |
| "Error: No such image: myuser/api:latest\n" | |
| "\n" | |
| "The tag command references 'myuser/api:latest' but no image with that tag exists." | |
| ), | |
| "exit_code": 1, | |
| "failed_step": "Tag latest", | |
| }, | |
| "expected_fixes": [ | |
| { | |
| "file": ".github/workflows/publish.yml", | |
| "type": "contains", | |
| "expected": "docker tag myuser/api:${{ github.sha }}", | |
| "hint": "The 'docker tag' source must match the tag used in the build step — use the sha-tagged image as source", | |
| } | |
| ], | |
| }, | |
| # Scenario 4: Dockerfile ARG not passed from workflow build-arg | |
| { | |
| "id": "build_arg_not_passed", | |
| "files": [ | |
| { | |
| "path": ".github/workflows/build.yml", | |
| "type": "workflow", | |
| "content": ( | |
| "name: Build with Version\n" | |
| "on:\n" | |
| " push:\n" | |
| " branches: [main]\n" | |
| "\n" | |
| "jobs:\n" | |
| " build:\n" | |
| " runs-on: ubuntu-latest\n" | |
| " steps:\n" | |
| " - uses: actions/checkout@v4\n" | |
| "\n" | |
| " - name: Build image\n" | |
| " run: docker build -t myapp:${{ github.sha }} .\n" | |
| ), | |
| }, | |
| { | |
| "path": "Dockerfile", | |
| "type": "dockerfile", | |
| "content": ( | |
| "FROM python:3.11-slim\n" | |
| "ARG APP_VERSION\n" | |
| "WORKDIR /app\n" | |
| "COPY . .\n" | |
| "RUN echo $APP_VERSION > /app/version.txt\n" | |
| "EXPOSE 7860\n" | |
| 'CMD ["python", "app.py"]\n' | |
| ), | |
| }, | |
| ], | |
| "error": { | |
| "phase": "pipeline_build", | |
| "message": ( | |
| "Run: Build with Version\n" | |
| "\n" | |
| "Step: Build image ✓ (with warnings)\n" | |
| "Warning: /app/version.txt is empty — APP_VERSION build arg was not provided\n" | |
| "\n" | |
| "The Dockerfile declares ARG APP_VERSION but the docker build command " | |
| "does not pass --build-arg APP_VERSION=..." | |
| ), | |
| "exit_code": 0, | |
| "failed_step": "Build image", | |
| }, | |
| "expected_fixes": [ | |
| { | |
| "file": ".github/workflows/build.yml", | |
| "type": "contains", | |
| "expected": "--build-arg APP_VERSION=", | |
| "hint": "Dockerfile uses ARG APP_VERSION but the build command doesn't pass --build-arg", | |
| } | |
| ], | |
| }, | |
| # Scenario 5: Dockerfile path wrong in workflow when using subdirectory structure | |
| { | |
| "id": "dockerfile_path_in_subdirectory", | |
| "files": [ | |
| { | |
| "path": ".github/workflows/build.yml", | |
| "type": "workflow", | |
| "content": ( | |
| "name: Build API\n" | |
| "on:\n" | |
| " push:\n" | |
| " branches: [main]\n" | |
| "\n" | |
| "jobs:\n" | |
| " build:\n" | |
| " runs-on: ubuntu-latest\n" | |
| " steps:\n" | |
| " - uses: actions/checkout@v4\n" | |
| "\n" | |
| " - name: Build API image\n" | |
| " uses: docker/build-push-action@v5\n" | |
| " with:\n" | |
| " context: ./services/api\n" | |
| " file: ./Dockerfile\n" | |
| " push: false\n" | |
| " tags: api:latest\n" | |
| ), | |
| }, | |
| { | |
| "path": "services/api/Dockerfile", | |
| "type": "dockerfile", | |
| "content": ( | |
| "FROM python:3.11-slim\n" | |
| "WORKDIR /app\n" | |
| "COPY requirements.txt .\n" | |
| "RUN pip install -r requirements.txt\n" | |
| "COPY . .\n" | |
| "EXPOSE 7860\n" | |
| 'CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]\n' | |
| ), | |
| }, | |
| { | |
| "path": "services/api/requirements.txt", | |
| "type": "requirements", | |
| "content": "fastapi==0.104.0\nuvicorn==0.24.0\n", | |
| }, | |
| ], | |
| "error": { | |
| "phase": "pipeline_build", | |
| "message": ( | |
| "Run: Build API\n" | |
| "\n" | |
| "Step: Build API image ✗\n" | |
| "Error: unable to prepare context: unable to evaluate symlinks in Dockerfile path: " | |
| "lstat /home/runner/work/repo/repo/Dockerfile: no such file or directory\n" | |
| "\n" | |
| "The Dockerfile is not at the repository root." | |
| ), | |
| "exit_code": 1, | |
| "failed_step": "Build API image", | |
| }, | |
| "expected_fixes": [ | |
| { | |
| "file": ".github/workflows/build.yml", | |
| "type": "contains", | |
| "expected": "file: ./services/api/Dockerfile", | |
| "hint": "The 'file' path must point to where the Dockerfile actually is — ./services/api/Dockerfile, not ./Dockerfile", | |
| } | |
| ], | |
| }, | |
| ] | |