mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-10-09 03:20:54 +00:00
Some checks failed
CI / Python packages / Build and verify distributions (push) Waiting to run
CI / Python quality / GitHub Actions (push) Waiting to run
CI / Python quality / Pre-commit (push) Waiting to run
CI / Python tests / Unit Tests - py3.11 (push) Waiting to run
CI / Python tests / Unit Tests - py3.12 (push) Waiting to run
CI / Python tests / Unit Tests - py3.13 (push) Waiting to run
CI / Python tests / Unit Tests - py3.14 (push) Waiting to run
CI / Windows / CLI smoke - py3.11 (push) Waiting to run
Deploy / Documentation / Build documentation (push) Waiting to run
Deploy / Documentation / deploy (push) Blocked by required conditions
CI and Release / Docker / Build and test / amd64 (push) Waiting to run
CI and Release / Docker / Build and test / arm64 (push) Waiting to run
CI and Release / Docker / Publish multi-platform tags (push) Blocked by required conditions
Security / CodeQL / Analyze javascript-typescript (push) Waiting to run
Security / CodeQL / Analyze python (push) Waiting to run
CI / ReMe Studio / Studio checks (push) Has been cancelled
* feat(docker): add container deployment and multi-platform release workflow * fix(llm): initialize providers on model access and preserve runtime injection * test(llm): keep rejected model updates independent of credentials
221 lines
7.5 KiB
YAML
221 lines
7.5 KiB
YAML
name: CI and Release / Docker
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
paths:
|
|
- '.github/workflows/docker.yml'
|
|
- 'Dockerfile'
|
|
- '.dockerignore'
|
|
- 'docker-compose.yml'
|
|
- 'deploy/docker/**'
|
|
- 'pyproject.toml'
|
|
- 'README.md'
|
|
- 'LICENSE'
|
|
- 'reme/**'
|
|
- 'reme_studio/**'
|
|
- 'scripts/package_studio.py'
|
|
- 'scripts/test_docker_image.py'
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- '.github/workflows/docker.yml'
|
|
- 'Dockerfile'
|
|
- '.dockerignore'
|
|
- 'docker-compose.yml'
|
|
- 'deploy/docker/**'
|
|
- 'pyproject.toml'
|
|
- 'README.md'
|
|
- 'LICENSE'
|
|
- 'reme/**'
|
|
- 'reme_studio/**'
|
|
- 'scripts/package_studio.py'
|
|
- 'scripts/test_docker_image.py'
|
|
release:
|
|
types: [published]
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
|
|
env:
|
|
PUBLISH_IMAGE: ${{ github.event_name == 'release' || (github.event_name != 'pull_request' && github.ref == 'refs/heads/main') }}
|
|
|
|
jobs:
|
|
build:
|
|
name: Build and test / ${{ matrix.arch }}
|
|
runs-on: ${{ matrix.runner }}
|
|
timeout-minutes: 60
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- arch: amd64
|
|
runner: ubuntu-24.04
|
|
- arch: arm64
|
|
runner: ubuntu-24.04-arm
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
with:
|
|
python-version: '3.11'
|
|
|
|
- name: Validate package version
|
|
env:
|
|
RELEASE_VERSION: ${{ github.event.release.tag_name }}
|
|
run: |
|
|
python -m pip install packaging
|
|
if [ -n "$RELEASE_VERSION" ]; then
|
|
python scripts/bump_version.py --check --expected-version "$RELEASE_VERSION"
|
|
else
|
|
python scripts/bump_version.py --check
|
|
fi
|
|
|
|
- name: Normalize image name
|
|
id: image
|
|
env:
|
|
REPOSITORY: ${{ github.repository }}
|
|
run: echo "name=ghcr.io/${REPOSITORY,,}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Validate Compose
|
|
run: docker compose config --quiet
|
|
|
|
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
|
|
|
|
- uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
|
|
id: metadata
|
|
with:
|
|
images: ${{ steps.image.outputs.name }}
|
|
flavor: latest=${{ github.event_name == 'release' && !github.event.release.prerelease && 'auto' || 'false' }}
|
|
tags: |
|
|
type=raw,value=main,enable=${{ github.ref == 'refs/heads/main' }}
|
|
type=pep440,pattern={{version}},value=${{ github.event.release.tag_name }},enable=${{ github.event_name == 'release' }}
|
|
type=sha
|
|
|
|
- name: Build local image
|
|
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7
|
|
with:
|
|
context: .
|
|
platforms: linux/${{ matrix.arch }}
|
|
load: true
|
|
tags: reme:smoke
|
|
labels: ${{ steps.metadata.outputs.labels }}
|
|
cache-from: type=gha,scope=reme-${{ matrix.arch }}
|
|
cache-to: type=gha,mode=max,scope=reme-${{ matrix.arch }}
|
|
|
|
- name: Test installed image and persistent workspace
|
|
run: python scripts/test_docker_image.py --image reme:smoke
|
|
|
|
- name: Log in to GHCR
|
|
if: env.PUBLISH_IMAGE == 'true'
|
|
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Publish tested architecture by digest
|
|
id: publish
|
|
if: env.PUBLISH_IMAGE == 'true'
|
|
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7
|
|
with:
|
|
context: .
|
|
platforms: linux/${{ matrix.arch }}
|
|
outputs: type=image,name=${{ steps.image.outputs.name }},push-by-digest=true,name-canonical=true,push=true
|
|
labels: ${{ steps.metadata.outputs.labels }}
|
|
cache-from: type=gha,scope=reme-${{ matrix.arch }}
|
|
provenance: mode=max
|
|
sbom: true
|
|
|
|
- name: Record image digest
|
|
if: env.PUBLISH_IMAGE == 'true'
|
|
env:
|
|
IMAGE_DIGEST: ${{ steps.publish.outputs.digest }}
|
|
run: |
|
|
mkdir -p "$RUNNER_TEMP/digests"
|
|
touch "$RUNNER_TEMP/digests/${IMAGE_DIGEST#sha256:}"
|
|
|
|
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: env.PUBLISH_IMAGE == 'true'
|
|
with:
|
|
name: docker-digest-${{ matrix.arch }}
|
|
path: ${{ runner.temp }}/digests/*
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
manifest:
|
|
name: Publish multi-platform tags
|
|
needs: build
|
|
if: github.event_name == 'release' || (github.event_name != 'pull_request' && github.ref == 'refs/heads/main')
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 15
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
steps:
|
|
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
pattern: docker-digest-*
|
|
merge-multiple: true
|
|
path: ${{ runner.temp }}/digests
|
|
|
|
- name: Normalize image name
|
|
id: image
|
|
env:
|
|
REPOSITORY: ${{ github.repository }}
|
|
run: echo "name=ghcr.io/${REPOSITORY,,}" >> "$GITHUB_OUTPUT"
|
|
|
|
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
|
|
|
|
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
|
|
id: metadata
|
|
with:
|
|
images: ${{ steps.image.outputs.name }}
|
|
flavor: latest=${{ github.event_name == 'release' && !github.event.release.prerelease && 'auto' || 'false' }}
|
|
tags: |
|
|
type=raw,value=main,enable=${{ github.ref == 'refs/heads/main' }}
|
|
type=pep440,pattern={{version}},value=${{ github.event.release.tag_name }},enable=${{ github.event_name == 'release' }}
|
|
type=sha
|
|
|
|
- name: Assemble and verify tags
|
|
env:
|
|
IMAGE_NAME: ${{ steps.image.outputs.name }}
|
|
IMAGE_TAGS: ${{ steps.metadata.outputs.tags }}
|
|
run: |
|
|
set -euo pipefail
|
|
image_refs=()
|
|
for digest_file in "$RUNNER_TEMP"/digests/*; do
|
|
image_refs+=("${IMAGE_NAME}@sha256:$(basename "$digest_file")")
|
|
done
|
|
[ "${#image_refs[@]}" -eq 2 ]
|
|
tag_args=()
|
|
while IFS= read -r tag; do
|
|
tag_args+=(--tag "$tag")
|
|
done <<< "$IMAGE_TAGS"
|
|
docker buildx imagetools create "${tag_args[@]}" "${image_refs[@]}"
|
|
while IFS= read -r tag; do
|
|
manifest=$(docker buildx imagetools inspect "$tag" --raw)
|
|
IMAGE_MANIFEST="$manifest" python - <<'PY'
|
|
import json
|
|
import os
|
|
manifest = json.loads(os.environ["IMAGE_MANIFEST"])
|
|
platforms = {(item["platform"]["os"], item["platform"]["architecture"]) for item in manifest["manifests"]}
|
|
assert {("linux", "amd64"), ("linux", "arm64")} <= platforms, platforms
|
|
PY
|
|
done <<< "$IMAGE_TAGS"
|