name: Build and Publish Container on: workflow_dispatch: env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} # For automatic pushes to Hugging Face Spaces, add # 'HF_TOKEN' as a repository secret pointing to a Hugging Face access token # with 'repo' scope for the target space `MCP-1st-Birthday/Roslyn-Stone`. jobs: build-and-push: name: Build and Push Container Image environment: name: production runs-on: ubuntu-latest timeout-minutes: 45 permissions: contents: read packages: write id-token: write attestations: write steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Log in to GitHub Container Registry if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract Docker metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha,prefix={{branch}}- type=raw,value=latest,enable={{is_default_branch}} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push Docker image uses: docker/build-push-action@v6 id: build timeout-minutes: 30 with: context: . file: ./src/RoslynStone.Api/Dockerfile push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max platforms: linux/amd64,linux/arm64 - name: Generate artifact attestation if: github.event_name != 'pull_request' uses: actions/attest-build-provenance@v2 with: subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} subject-digest: ${{ steps.build.outputs.digest }} push-to-registry: true # Upload repository or built artifacts to Hugging Face Space - name: Set up Python for `hf` CLI if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' uses: actions/setup-python@v4 with: python-version: '3.11' - name: Install HF CLI if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' timeout-minutes: 2 run: | python -m pip install --upgrade pip pip install huggingface-hub # Try to install the `uvx` wrapper if available; do not fail if not published pip install uvx || true command -v uvx || true hf --version || true env: HF_TOKEN: ${{ secrets.HF_TOKEN }} - name: Login to Hugging Face (non-interactive using token) if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' timeout-minutes: 1 run: | set -eux if [ -z "${HF_TOKEN}" ]; then echo "HF_TOKEN missing; skipping 'hf auth login'"; exit 0; fi # Try uvx hugging-cli if available if command -v uvx >/dev/null 2>&1; then uvx hugging-cli login --token "${HF_TOKEN}" || true fi hf auth login --token "${HF_TOKEN}" env: HF_TOKEN: ${{ secrets.HF_TOKEN }} - name: Upload to Hugging Face Space (using uvx if available, else hf) if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' timeout-minutes: 10 run: | # Use uvx wrapper if present, otherwise use hf CLI directly. # This uploads the repository root while excluding common build and binary dirs. set -eux if [ -z "${HF_TOKEN}" ]; then echo "HF_TOKEN is not set; skipping Hugging Face upload."; exit 0; fi # Upload the repository root to the Space, excluding common build outputs if command -v uvx >/dev/null 2>&1; then uvx hf upload MCP-1st-Birthday/Roslyn-Stone . --repo-type=space --exclude="/.venv/*" --exclude="/bin/*" --exclude="/obj/*" --exclude="/tests/*" --exclude="/.github/*" --delete="*" --commit-message="CI: Sync from GitHub Actions ${GITHUB_SHA}" else hf upload MCP-1st-Birthday/Roslyn-Stone . --repo-type=space --exclude="/.venv/*" --exclude="/bin/*" --exclude="/obj/*" --exclude="/tests/*" --exclude="/.github/*" --delete="*" --commit-message="CI: Sync from GitHub Actions ${GITHUB_SHA}" fi env: HF_TOKEN: ${{ secrets.HF_TOKEN }}