cloudnative-devops-debug-env / server /tasks /pipeline_build_deploy.py
Krishna1107's picture
inference fixed, port changed to 7860
eb895b1
"""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",
}
],
},
]