Skip to content

Merge pull request #82 from usnavy13/dev #10

Merge pull request #82 from usnavy13/dev

Merge pull request #82 from usnavy13/dev #10

Workflow file for this run

name: Release Images
on:
push:
branches: [main, dev]
tags: ["v*.*.*"]
workflow_dispatch:
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
packages: write
env:
PYTHON_VERSION: "3.11"
REGISTRY_IMAGE: ghcr.io/usnavy13/librecodeinterpreter
RUNTIME_R_IMAGE: ghcr.io/usnavy13/librecodeinterpreter/runtime-r
BUILDCACHE_IMAGE: ghcr.io/usnavy13/librecodeinterpreter/buildcache
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
runtime_hash: ${{ steps.runtime.outputs.runtime_hash }}
sha_tag: ${{ steps.tags.outputs.sha_tag }}
moving_tag: ${{ steps.tags.outputs.moving_tag }}
version_tag: ${{ steps.tags.outputs.version_tag }}
steps:
- uses: actions/checkout@v4
- id: runtime
run: echo "runtime_hash=$(scripts/ci/compute_runtime_hash.sh)" >> "${GITHUB_OUTPUT}"
- id: tags
run: |
echo "sha_tag=sha-${GITHUB_SHA}" >> "${GITHUB_OUTPUT}"
if [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then
echo "moving_tag=main" >> "${GITHUB_OUTPUT}"
elif [[ "${GITHUB_REF}" == "refs/heads/dev" ]]; then
echo "moving_tag=dev" >> "${GITHUB_OUTPUT}"
else
echo "moving_tag=" >> "${GITHUB_OUTPUT}"
fi
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
echo "version_tag=${GITHUB_REF#refs/tags/}" >> "${GITHUB_OUTPUT}"
else
echo "version_tag=" >> "${GITHUB_OUTPUT}"
fi
build-app:
needs: [prepare]
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
platform: linux/amd64
runner: ubuntu-24.04
- arch: arm64
platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: runtime
name: Resolve runtime base
run: |
runtime_base="$(scripts/ci/resolve_runtime_base.sh "${RUNTIME_R_IMAGE}" "${{ needs.prepare.outputs.runtime_hash }}")"
echo "runtime_base=${runtime_base}" >> "${GITHUB_OUTPUT}"
- name: Build and push app image
uses: docker/build-push-action@v6
with:
context: .
target: app
push: true
platforms: ${{ matrix.platform }}
provenance: false
tags: ${{ env.REGISTRY_IMAGE }}:${{ github.sha }}-${{ matrix.arch }}
build-args: |
RUNTIME_R_BASE=${{ steps.runtime.outputs.runtime_base }}
cache-from: |
type=registry,ref=${{ env.BUILDCACHE_IMAGE }}:app-${{ matrix.arch }}
type=registry,ref=${{ env.BUILDCACHE_IMAGE }}:runtime-r-${{ matrix.arch }}
cache-to: type=registry,ref=${{ env.BUILDCACHE_IMAGE }}:app-${{ matrix.arch }},mode=max
smoke:
needs: [prepare, build-app]
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-24.04
- arch: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: pip
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Install test dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-asyncio pytest-cov pytest-mock
- name: Pull release candidate
run: docker pull "${REGISTRY_IMAGE}:${GITHUB_SHA}-${{ matrix.arch }}"
- name: Start smoke stack
env:
API_IMAGE: ${{ env.REGISTRY_IMAGE }}:${{ github.sha }}-${{ matrix.arch }}
run: |
cp .env.example .env
docker compose up -d
- name: Wait for API
run: |
if ! scripts/ci/wait_for_api.sh http://localhost:8000/health 24 5; then
docker compose logs --no-color api
exit 1
fi
- name: Run release smoke suite
env:
API_BASE: http://localhost:8000
API_KEY: your-secure-api-key-here-change-this-in-production
run: |
mkdir -p test-results
pytest \
tests/functional/test_health.py \
tests/functional/test_exec_workflow.py::TestSessionWorkflow::test_execution_creates_session \
tests/functional/test_files.py::TestFileUpload::test_upload_single_file \
tests/functional/test_ptc.py::TestPTCInitialExecution::test_ptc_simple_code_completes \
-v \
--junitxml=test-results/release-smoke-${{ matrix.arch }}.xml
- name: Capture compose logs on failure
if: failure()
run: docker compose logs --no-color > release-compose-${{ matrix.arch }}.log
- name: Upload release smoke artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: release-smoke-${{ matrix.arch }}
path: |
test-results/
release-compose-${{ matrix.arch }}.log
if-no-files-found: ignore
- name: Stop smoke stack
if: always()
run: docker compose down -v
publish-manifest:
needs: [prepare, smoke]
runs-on: ubuntu-latest
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Publish multi-arch manifest tags
run: |
tags=(
"-t" "${REGISTRY_IMAGE}:${{ needs.prepare.outputs.sha_tag }}"
)
if [[ -n "${{ needs.prepare.outputs.moving_tag }}" ]]; then
tags+=("-t" "${REGISTRY_IMAGE}:${{ needs.prepare.outputs.moving_tag }}")
fi
if [[ -n "${{ needs.prepare.outputs.version_tag }}" ]]; then
tags+=("-t" "${REGISTRY_IMAGE}:${{ needs.prepare.outputs.version_tag }}")
fi
docker buildx imagetools create \
"${tags[@]}" \
"${REGISTRY_IMAGE}:${GITHUB_SHA}-amd64" \
"${REGISTRY_IMAGE}:${GITHUB_SHA}-arm64"