diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..1810e3aa --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +name: CI + +on: + push: + branches: [main] + paths: + - "db/migrations/**" + pull_request: + branches: [main] + paths: + - "db/migrations/**" + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + migrate: + runs-on: ubuntu-latest + services: + postgres: + image: postgres:18-alpine + env: + POSTGRES_DB: memoh_test + POSTGRES_USER: memoh + POSTGRES_PASSWORD: memoh123 + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U memoh" + --health-interval 5s + --health-timeout 3s + --health-retries 5 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - name: Build + run: go build -o memoh-server ./cmd/agent + + - name: Generate config + run: | + cat > config.toml <<'TOML' + [postgres] + host = "127.0.0.1" + port = 5432 + user = "memoh" + password = "memoh123" + database = "memoh_test" + sslmode = "disable" + TOML + + - name: Migrate up + run: ./memoh-server migrate up + + - name: Migrate down + run: ./memoh-server migrate down + + - name: Migrate up (idempotent) + run: ./memoh-server migrate up diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 00000000..829a87e3 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,99 @@ +name: Docker Publish + +on: + push: + tags: ["v*.*.*"] + pull_request: + branches: [main] + paths-ignore: + - "docs/**" + - "**.md" + - "devenv/**" + workflow_dispatch: + +concurrency: + group: docker-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + packages: write + id-token: write + +jobs: + docker: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - image: server + dockerfile: docker/Dockerfile.server + - image: agent + dockerfile: docker/Dockerfile.agent + - image: web + dockerfile: docker/Dockerfile.web + - image: mcp + dockerfile: docker/Dockerfile.mcp + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + memohai/${{ matrix.image }} + ghcr.io/${{ github.repository_owner }}/${{ matrix.image }} + tags: | + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-') }} + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + labels: | + org.opencontainers.image.title=memoh-${{ matrix.image }} + org.opencontainers.image.description=Memoh ${{ matrix.image }} - Multi-member AI agent platform + org.opencontainers.image.vendor=memohai + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + if: startsWith(github.ref, 'refs/tags/') + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Login to GitHub Container Registry + if: startsWith(github.ref, 'refs/tags/') + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: ${{ matrix.dockerfile }} + push: ${{ startsWith(github.ref, 'refs/tags/') }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: ${{ startsWith(github.ref, 'refs/tags/') && 'linux/amd64,linux/arm64' || 'linux/amd64' }} + build-args: | + VERSION=${{ steps.meta.outputs.version }} + COMMIT_HASH=${{ github.sha }} + BUILD_TIME=${{ fromJson(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} + VITE_API_URL=/api + VITE_AGENT_URL=/agent + provenance: true + sbom: true + cache-from: type=gha,scope=${{ matrix.image }} + cache-to: type=gha,scope=${{ matrix.image }},mode=max diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e1ef2cab..ccce14cd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,13 +8,9 @@ on: push: tags: - 'v*' - release: - types: - - published jobs: release: - if: github.event_name == 'push' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -39,47 +35,3 @@ jobs: # env: # NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} # NPM_CONFIG_PROVENANCE: true - - dockerhub: - if: github.event_name == 'release' - runs-on: ubuntu-latest - strategy: - matrix: - include: - - image: server - dockerfile: docker/Dockerfile.server - - image: agent - dockerfile: docker/Dockerfile.agent - - image: web - dockerfile: docker/Dockerfile.web - steps: - - uses: actions/checkout@v4 - - - name: Set build time - id: vars - run: echo "build_time=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT" - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push multi-arch image - uses: docker/build-push-action@v6 - with: - context: . - file: ${{ matrix.dockerfile }} - platforms: linux/amd64,linux/arm64 - push: true - tags: memohai/${{ matrix.image }}:${{ github.event.release.tag_name }} - build-args: | - VERSION=${{ github.event.release.tag_name }} - COMMIT_HASH=${{ github.sha }} - BUILD_TIME=${{ steps.vars.outputs.build_time }} \ No newline at end of file