name: docker-image # Build + push the app image to GHCR on every master push, so pull-only # hosts (TrueNAS SCALE custom apps) can deploy without a repo checkout. on: push: branches: [master] paths: - "Dockerfile" - "requirements.txt" - "**.py" - ".github/workflows/docker.yml" workflow_dispatch: jobs: # Gate: no image reaches a registry unless the suite is green. Production # (TrueNAS) pulls :latest blindly, so this job is the only test run between # a master push and the live loop. test: runs-on: ubuntu-latest services: postgres: image: postgres:18 # keep matched to the compose files' server image env: POSTGRES_USER: momentum POSTGRES_PASSWORD: momentum POSTGRES_DB: momentum ports: ["5432:5432"] options: >- --health-cmd "pg_isready -U momentum" --health-interval 5s --health-timeout 5s --health-retries 10 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: { python-version: "3.13" } # match Dockerfile's python:3.13-slim - run: pip install -r requirements.txt ruff # ruff F gate, scoped to the money path (tests/ and root-level scratch # scripts excluded). All per-file pins have been cleared as their owning # plans landed (api/main.py F821 os/hmac -> plan 007), so this is unpinned. - run: >- ruff check --select F run_live_paper.py trading_execution.py telegram_bot.py api/ alpaca_paper/ runtime/ storage/ strategy/ research/ - run: python -m pytest -q env: DATABASE_URL: postgresql://momentum:momentum@localhost:5432/momentum # tests were written under an ET wall clock (the app image pins it too) TZ: America/New_York build: needs: test runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v4 - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - id: ver run: echo "tag=$(date -u +%Y.%m.%d)-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" - uses: docker/build-push-action@v6 with: context: . push: true build-args: | GIT_SHA=${{ github.sha }} BUILD_TAG=${{ steps.ver.outputs.tag }} tags: | ghcr.io/fez5587/momentum-app:latest ghcr.io/fez5587/momentum-app:${{ github.sha }} ghcr.io/fez5587/momentum-app:${{ steps.ver.outputs.tag }} fez5587/momentum-app:latest fez5587/momentum-app:${{ github.sha }} fez5587/momentum-app:${{ steps.ver.outputs.tag }}