diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a51feed..023a4259 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,7 @@ on: env: go-version: '1.21.5' + python-version: '3.12' cmd-name: 'greenmask' docker-registry: greenmask/greenmask @@ -30,10 +31,10 @@ jobs: uses: actions/setup-go@v5 with: go-version: ${{ env.go-version }} - + - name: Echo Go version run: go version - + - name: Run tests run: make tests @@ -47,17 +48,17 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v3 - + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - + - name: Run integration tests run: | docker-compose -f docker-compose-integration.yml -p greenmask up \ --renew-anon-volumes --force-recreate --build --exit-code-from greenmask \ --abort-on-container-exit greenmask - binaries: + build-binaries: runs-on: ubuntu-22.04 needs: - unit-tests @@ -84,7 +85,7 @@ jobs: uses: actions/setup-go@v5 with: go-version: ${{ env.go-version }} - + - name: Build with different arch run: | export GOOS=$(echo ${{ matrix.platforms }} | cut -d '/' -f 1) @@ -130,7 +131,7 @@ jobs: build-docker-images-and-push: runs-on: ubuntu-22.04 needs: - - binaries + - build-binaries if: startsWith(github.ref, 'refs/tags/v') steps: - name: Checkout repository @@ -160,3 +161,39 @@ jobs: platforms: linux/amd64,linux/arm64 push: true tags: ${{ env.docker-registry }}:${{ env.TAG }},${{ env.docker-registry }}:latest + + deploy-docs: + runs-on: self-hosted + needs: + - build-binaries + - build-docker-images-and-push + if: startsWith(github.ref, 'refs/tags/v') + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup python + uses: actions/setup-python@v5 + with: + python-version: ${{ env.python-version }} + + - name: Install dependicies + run: pip install -r requirements.txt + + - name: Build docs + run: mkdocs build + + - name: Create docs directory + run: sudo mkdir -p ${{ secrets.DOCS_DEPLOY_DIR }} + + - name: Move html files to docs directory + run: sudo mv site ${{ secrets.DOCS_DEPLOY_DIR }}/html-${{ github.ref_name}} + + - name: Remove old symlink + run: sudo unlink ${{ secrets.DOCS_DEPLOY_DIR }}/html + + - name: Create new symlink + run: sudo ln -s ${{ secrets.DOCS_DEPLOY_DIR }}/html-${{ github.ref_name}} ${{ secrets.DOCS_DEPLOY_DIR }}/html + + - name: Restart web service + run: sudo systemctl restart nginx diff --git a/internal/db/postgres/restorers/table.go b/internal/db/postgres/restorers/table.go index cc3db25c..9641f360 100644 --- a/internal/db/postgres/restorers/table.go +++ b/internal/db/postgres/restorers/table.go @@ -44,6 +44,10 @@ func NewTableRestorer(entry *toc.Entry, st storages.Storager) *TableRestorer { } func (td *TableRestorer) Execute(ctx context.Context, tx pgx.Tx) error { + // TODO: Refactor this logic + // 1. Decompose the Execute method into separate functions + // 2. Add tests + // 3. Get rid of the anonymous functions below return func() error { if td.Entry.FileName == nil { @@ -63,12 +67,10 @@ func (td *TableRestorer) Execute(ctx context.Context, tx pgx.Tx) error { log.Debug().Str("copyStmt", *td.Entry.CopyStmt).Msgf("performing pgcopy statement") frontend := tx.Conn().PgConn().Frontend() - frontend.Send(&pgproto3.Query{ - String: *td.Entry.CopyStmt, - }) - if err = frontend.Flush(); err != nil { - return err + err = sendMessage(frontend, &pgproto3.Query{String: *td.Entry.CopyStmt}) + if err != nil { + return fmt.Errorf("error sending Query message: %w", err) } // Prepare for streaming the pgcopy data @@ -108,19 +110,19 @@ func (td *TableRestorer) Execute(ctx context.Context, tx pgx.Tx) error { n, err = gz.Read(buf) if err != nil { if errors.Is(err, io.EOF) { - frontend.Send(&pgproto3.CopyDone{}) + completionErr := sendMessage(frontend, &pgproto3.CopyDone{}) + if completionErr != nil { + return fmt.Errorf("error sending CopyDone message: %w", err) + } break } return fmt.Errorf("error readimg from table dump: %w", err) } - frontend.Send(&pgproto3.CopyData{ - Data: buf[:n], - }) - } - - if err = frontend.Flush(); err != nil { - return err + err = sendMessage(frontend, &pgproto3.CopyData{Data: buf[:n]}) + if err != nil { + return fmt.Errorf("error sending DopyData message: %w", err) + } } // Perform post streaming handling @@ -152,3 +154,12 @@ func (td *TableRestorer) Execute(ctx context.Context, tx pgx.Tx) error { func (td *TableRestorer) DebugInfo() string { return fmt.Sprintf("table %s.%s", *td.Entry.Namespace, *td.Entry.Tag) } + +// sendMessage - send a message to the PostgreSQL backend and flush a buffer +func sendMessage(frontend *pgproto3.Frontend, msg pgproto3.FrontendMessage) error { + frontend.Send(msg) + if err := frontend.Flush(); err != nil { + return fmt.Errorf("error flushing pgx frontend buffer: %w", err) + } + return nil +}