|
|
@@ -1,4 +1,4 @@
|
|
|
-name: Publish Docker Image
|
|
|
+name: Build Publish and Test Docker Image
|
|
|
|
|
|
concurrency:
|
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
|
@@ -7,7 +7,7 @@ concurrency:
|
|
|
on:
|
|
|
push:
|
|
|
branches:
|
|
|
- - main
|
|
|
+ - main
|
|
|
tags:
|
|
|
- '*'
|
|
|
pull_request:
|
|
|
@@ -19,19 +19,23 @@ on:
|
|
|
default: ''
|
|
|
|
|
|
jobs:
|
|
|
- ghcr_build_and_push:
|
|
|
+ ghcr_build:
|
|
|
runs-on: ubuntu-latest
|
|
|
|
|
|
+ outputs:
|
|
|
+ tags: ${{ steps.capture-tags.outputs.tags }}
|
|
|
+
|
|
|
permissions:
|
|
|
contents: read
|
|
|
packages: write
|
|
|
|
|
|
strategy:
|
|
|
matrix:
|
|
|
- image: ["app", "sandbox"]
|
|
|
+ image: ["sandbox", "opendevin"]
|
|
|
+ platform: ["amd64", "arm64"]
|
|
|
|
|
|
steps:
|
|
|
- - name: checkout
|
|
|
+ - name: Checkout
|
|
|
uses: actions/checkout@v4
|
|
|
|
|
|
- name: Free Disk Space (Ubuntu)
|
|
|
@@ -40,7 +44,6 @@ jobs:
|
|
|
# this might remove tools that are actually needed,
|
|
|
# if set to "true" but frees about 6 GB
|
|
|
tool-cache: true
|
|
|
-
|
|
|
# all of these default to true, but feel free to set to
|
|
|
# "false" if necessary for your workflow
|
|
|
android: true
|
|
|
@@ -57,26 +60,207 @@ jobs:
|
|
|
id: buildx
|
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
|
|
- - name: Login to ghcr
|
|
|
- uses: docker/login-action@v1
|
|
|
+ - name: Build and export image
|
|
|
+ id: build
|
|
|
+ run: ./containers/build.sh ${{ matrix.image }} ${{ github.repository_owner }} ${{ matrix.platform }}
|
|
|
+
|
|
|
+ - name: Capture tags
|
|
|
+ id: capture-tags
|
|
|
+ run: |
|
|
|
+ tags=$(cat tags.txt)
|
|
|
+ echo "tags=$tags"
|
|
|
+ echo "tags=$tags" >> $GITHUB_OUTPUT
|
|
|
+
|
|
|
+ - name: Upload Docker image as artifact
|
|
|
+ uses: actions/upload-artifact@v4
|
|
|
+ with:
|
|
|
+ name: ${{ matrix.image }}-docker-image-${{ matrix.platform }}
|
|
|
+ path: /tmp/${{ matrix.image }}_image_${{ matrix.platform }}.tar
|
|
|
+
|
|
|
+ test-for-sandbox:
|
|
|
+ name: Test for Sandbox
|
|
|
+ runs-on: ubuntu-latest
|
|
|
+ needs: ghcr_build
|
|
|
+ env:
|
|
|
+ PERSIST_SANDBOX: "false"
|
|
|
+ steps:
|
|
|
+ - uses: actions/checkout@v4
|
|
|
+
|
|
|
+ - name: Install poetry via pipx
|
|
|
+ run: pipx install poetry
|
|
|
+
|
|
|
+ - name: Set up Python
|
|
|
+ uses: actions/setup-python@v5
|
|
|
+ with:
|
|
|
+ python-version: "3.11"
|
|
|
+ cache: "poetry"
|
|
|
+
|
|
|
+ - name: Install Python dependencies using Poetry
|
|
|
+ run: make install-python-dependencies
|
|
|
+
|
|
|
+ - name: Download sandbox Docker image
|
|
|
+ uses: actions/download-artifact@v4
|
|
|
+ with:
|
|
|
+ name: sandbox-docker-image-amd64
|
|
|
+ path: /tmp/
|
|
|
+
|
|
|
+ - name: Load sandbox image and run sandbox tests
|
|
|
+ run: |
|
|
|
+ # Load the Docker image and capture the output
|
|
|
+ output=$(docker load -i /tmp/sandbox_image_amd64.tar)
|
|
|
+
|
|
|
+ # Extract the image name from the output
|
|
|
+ image_name=$(echo "$output" | grep -oP 'Loaded image: \K.*')
|
|
|
+
|
|
|
+ # Print the full name of the image
|
|
|
+ echo "Loaded Docker image: $image_name"
|
|
|
+
|
|
|
+ SANDBOX_CONTAINER_IMAGE=$image_name poetry run pytest --cov=agenthub --cov=opendevin --cov-report=xml -s ./tests/unit/test_sandbox.py
|
|
|
+
|
|
|
+ - name: Upload coverage to Codecov
|
|
|
+ uses: codecov/codecov-action@v4
|
|
|
+ env:
|
|
|
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
|
+
|
|
|
+ integration-tests-on-linux:
|
|
|
+ name: Integration Tests on Linux
|
|
|
+ runs-on: ubuntu-latest
|
|
|
+ needs: ghcr_build
|
|
|
+ env:
|
|
|
+ PERSIST_SANDBOX: "false"
|
|
|
+ strategy:
|
|
|
+ fail-fast: false
|
|
|
+ matrix:
|
|
|
+ python-version: ["3.11"]
|
|
|
+ sandbox: ["ssh", "exec", "local"]
|
|
|
+ steps:
|
|
|
+ - uses: actions/checkout@v4
|
|
|
+
|
|
|
+ - name: Install poetry via pipx
|
|
|
+ run: pipx install poetry
|
|
|
+
|
|
|
+ - name: Set up Python
|
|
|
+ uses: actions/setup-python@v5
|
|
|
+ with:
|
|
|
+ python-version: ${{ matrix.python-version }}
|
|
|
+ cache: 'poetry'
|
|
|
+
|
|
|
+ - name: Install Python dependencies using Poetry
|
|
|
+ run: make install-python-dependencies
|
|
|
+
|
|
|
+ - name: Download sandbox Docker image
|
|
|
+ uses: actions/download-artifact@v4
|
|
|
+ with:
|
|
|
+ name: sandbox-docker-image-amd64
|
|
|
+ path: /tmp/
|
|
|
+
|
|
|
+ - name: Load sandbox image and run integration tests
|
|
|
+ env:
|
|
|
+ SANDBOX_TYPE: ${{ matrix.sandbox }}
|
|
|
+ run: |
|
|
|
+ # Load the Docker image and capture the output
|
|
|
+ output=$(docker load -i /tmp/sandbox_image_amd64.tar)
|
|
|
+
|
|
|
+ # Extract the image name from the output
|
|
|
+ image_name=$(echo "$output" | grep -oP 'Loaded image: \K.*')
|
|
|
+
|
|
|
+ # Print the full name of the image
|
|
|
+ echo "Loaded Docker image: $image_name"
|
|
|
+
|
|
|
+ SANDBOX_CONTAINER_IMAGE=$image_name TEST_IN_CI=true TEST_ONLY=true ./tests/integration/regenerate.sh
|
|
|
+
|
|
|
+ - name: Upload coverage to Codecov
|
|
|
+ uses: codecov/codecov-action@v4
|
|
|
+ env:
|
|
|
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
|
+
|
|
|
+ ghcr_push:
|
|
|
+ runs-on: ubuntu-latest
|
|
|
+ # don't push if integration tests or sandbox tests fail
|
|
|
+ needs: [ghcr_build, integration-tests-on-linux, test-for-sandbox]
|
|
|
+ if: github.ref == 'refs/heads/main'
|
|
|
+
|
|
|
+ env:
|
|
|
+ tags: ${{ needs.ghcr_build.outputs.tags }}
|
|
|
+
|
|
|
+ permissions:
|
|
|
+ contents: read
|
|
|
+ packages: write
|
|
|
+
|
|
|
+ strategy:
|
|
|
+ matrix:
|
|
|
+ image: ["sandbox", "opendevin"]
|
|
|
+ platform: ["amd64", "arm64"]
|
|
|
+
|
|
|
+ steps:
|
|
|
+ - name: Checkout code
|
|
|
+ uses: actions/checkout@v4
|
|
|
+
|
|
|
+ - name: Login to GHCR
|
|
|
+ uses: docker/login-action@v2
|
|
|
with:
|
|
|
registry: ghcr.io
|
|
|
username: ${{ github.repository_owner }}
|
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
|
|
- - name: Build and push ${{ matrix.image }}
|
|
|
- if: "!github.event.pull_request.head.repo.fork"
|
|
|
+ - name: Download Docker images
|
|
|
+ uses: actions/download-artifact@v4
|
|
|
+ with:
|
|
|
+ name: ${{ matrix.image }}-docker-image-${{ matrix.platform }}
|
|
|
+ path: /tmp/${{ matrix.platform }}
|
|
|
+
|
|
|
+ - name: Load images and push to registry
|
|
|
run: |
|
|
|
- ./containers/build.sh ${{ matrix.image }} ${{ github.repository_owner }} --push
|
|
|
+ mv /tmp/${{ matrix.platform }}/${{ matrix.image }}_image_${{ matrix.platform }}.tar .
|
|
|
+ loaded_image=$(docker load -i ${{ matrix.image }}_image_${{ matrix.platform }}.tar | grep "Loaded image:" | awk '{print $3}')
|
|
|
+ tags=$(echo ${tags} | tr ' ' '\n')
|
|
|
+ for tag in $tags; do
|
|
|
+ echo "tag = $tag"
|
|
|
+ docker tag $loaded_image ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}:${tag}_${{ matrix.platform }}
|
|
|
+ docker push ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}:${tag}_${{ matrix.platform }}
|
|
|
+ done
|
|
|
+
|
|
|
+ create_manifest:
|
|
|
+ runs-on: ubuntu-latest
|
|
|
+ needs: [ghcr_build, ghcr_push]
|
|
|
+ if: github.ref == 'refs/heads/main'
|
|
|
+
|
|
|
+ env:
|
|
|
+ tags: ${{ needs.ghcr_build.outputs.tags }}
|
|
|
+
|
|
|
+ strategy:
|
|
|
+ matrix:
|
|
|
+ image: ["sandbox", "opendevin"]
|
|
|
+
|
|
|
+ permissions:
|
|
|
+ contents: read
|
|
|
+ packages: write
|
|
|
+
|
|
|
+ steps:
|
|
|
+ - name: Checkout code
|
|
|
+ uses: actions/checkout@v4
|
|
|
+
|
|
|
+ - name: Login to GHCR
|
|
|
+ uses: docker/login-action@v2
|
|
|
+ with:
|
|
|
+ registry: ghcr.io
|
|
|
+ username: ${{ github.repository_owner }}
|
|
|
+ password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
|
|
- - name: Build ${{ matrix.image }}
|
|
|
- if: "github.event.pull_request.head.repo.fork"
|
|
|
+ - name: Create and push multi-platform manifest
|
|
|
run: |
|
|
|
- ./containers/build.sh ${{ matrix.image }} ${{ github.repository_owner }}
|
|
|
+ tags=$(echo ${tags} | tr ' ' '\n')
|
|
|
+ for tag in $tags; do
|
|
|
+ echo 'tag = $tag'
|
|
|
+ docker buildx imagetools create --tag ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}:$tag \
|
|
|
+ ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}:${tag}_amd64 \
|
|
|
+ ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}:${tag}_arm64
|
|
|
+ done
|
|
|
|
|
|
+ # FIXME: an admin needs to mark this as non-mandatory, and then we can remove it
|
|
|
docker_build_success:
|
|
|
name: Docker Build Success
|
|
|
runs-on: ubuntu-latest
|
|
|
- needs: ghcr_build_and_push
|
|
|
+ needs: ghcr_build
|
|
|
steps:
|
|
|
- run: echo Done!
|