Fix black lint, fix /processing-runs 404s, add semantic release and GitOps deploy
Agent-Logs-Url: https://github.com/christianlouis/InboxConverge/sessions/3fdf6219-3e1f-4867-b74d-efb6e4fe7e72 Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -224,3 +224,59 @@ jobs:
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
# ── Phase 5: GitOps – update preprod k8s manifest ─────────────────────────
|
||||
update-k8s-manifest:
|
||||
name: Update Preprod K8s Manifest
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build]
|
||||
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Compute image tags
|
||||
id: tag
|
||||
run: |
|
||||
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
|
||||
echo "backend_image=ghcr.io/${{ github.repository_owner }}/inboxconverge/backend:main-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
||||
echo "frontend_image=ghcr.io/${{ github.repository_owner }}/inboxconverge/frontend:main-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
||||
echo "short_sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Checkout k8s-cluster-state
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: christianlouis/k8s-cluster-state
|
||||
token: ${{ secrets.GH_PAT }}
|
||||
path: k8s-cluster-state
|
||||
|
||||
- name: Update backend image tag in preprod manifest
|
||||
uses: mikefarah/yq@v4.44.6
|
||||
env:
|
||||
IMAGE: ${{ steps.tag.outputs.backend_image }}
|
||||
with:
|
||||
cmd: |
|
||||
yq -i '(.. | select(tag == "!!str") | select(test("^ghcr\\.io/christianlouis/inboxconverge/backend:"))) = strenv(IMAGE)' \
|
||||
k8s-cluster-state/apps/gmail-puller/preprod/gmail-puller-stack.yaml
|
||||
|
||||
- name: Update frontend image tag in preprod manifest
|
||||
uses: mikefarah/yq@v4.44.6
|
||||
env:
|
||||
IMAGE: ${{ steps.tag.outputs.frontend_image }}
|
||||
with:
|
||||
cmd: |
|
||||
yq -i '(.. | select(tag == "!!str") | select(test("^ghcr\\.io/christianlouis/inboxconverge/frontend:"))) = strenv(IMAGE)' \
|
||||
k8s-cluster-state/apps/gmail-puller/preprod/gmail-puller-stack.yaml
|
||||
|
||||
- name: Commit and push manifest update
|
||||
run: |
|
||||
cd k8s-cluster-state
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add apps/gmail-puller/preprod/gmail-puller-stack.yaml
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes to commit"
|
||||
else
|
||||
git commit -m "chore(preprod): update inboxconverge images to ${{ steps.tag.outputs.short_sha }}"
|
||||
git push
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
name: Semantic Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
packages: write
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Semantic Release
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'christianlouis/InboxConverge'
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install python-semantic-release
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Run Semantic Release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
semantic-release version --print
|
||||
semantic-release version
|
||||
semantic-release publish
|
||||
|
||||
- name: Update changelog if no new version was released
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
if git diff --name-only HEAD~1 2>/dev/null | grep -q CHANGELOG.md; then
|
||||
echo "CHANGELOG.md was already updated by semantic-release version"
|
||||
else
|
||||
semantic-release changelog
|
||||
if ! git diff --quiet CHANGELOG.md; then
|
||||
git add CHANGELOG.md
|
||||
git commit -m "docs(changelog): update changelog [skip ci]"
|
||||
git push
|
||||
fi
|
||||
fi
|
||||
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
- **Black formatting**: `backend/app/api/v1/endpoints/admin.py` was not formatted correctly; reformatted to pass `black --check`.
|
||||
- **`/processing-runs` endpoint 404s**: Routes in `logs.py` had a redundant `/processing-runs` path segment (the router was already mounted at `/processing-runs` in `api.py`). All three user-facing log endpoints now return correct results:
|
||||
- `GET /processing-runs` (was: `GET /processing-runs/processing-runs`)
|
||||
- `GET /processing-runs/{id}` (was: `GET /processing-runs/processing-runs/{id}`)
|
||||
- `GET /processing-runs/{id}/logs` (was: `GET /processing-runs/processing-runs/{id}/logs`)
|
||||
|
||||
### Added
|
||||
- **Semantic Release** (`release.yml`): Automated versioning and GitHub Release creation on every push to `main` using `python-semantic-release`. Reads conventional-commit prefixes (`feat:`, `fix:`, etc.) to determine the next version and updates `CHANGELOG.md`.
|
||||
- **`pyproject.toml`**: Project metadata and `[tool.semantic_release]` configuration for `python-semantic-release`.
|
||||
- **GitOps auto-deployment** (step in `ci.yml`): After a successful Docker build on `main`, a new `update-k8s-manifest` job checks out `christianlouis/k8s-cluster-state` (using the `GH_PAT` secret) and updates the backend and frontend image tags in `apps/gmail-puller/preprod/gmail-puller-stack.yaml` to the new `main-<sha>` image, then commits and pushes.
|
||||
|
||||
### Changed
|
||||
- **Project renamed to InboxConverge**: All user-visible strings, Docker container names, database defaults, Docker image paths, monitoring job names, Grafana dashboard titles, and documentation updated from the legacy names (`POP3 to Gmail Forwarder`, `InboxRescue`, `gmail-puller`, `pop3_forwarder`, etc.) to **InboxConverge** / `inboxconverge`.
|
||||
- **Domain updated to `inboxconverge.com`**: All contact and administrative email addresses now default to `@inboxconverge.com` (e.g. `christian@inboxconverge.com`).
|
||||
|
||||
@@ -407,6 +407,8 @@ async def test_admin_notification_config(
|
||||
"""Test an admin notification channel by sending a test message (admin only)"""
|
||||
success, message = await test_notification(request.apprise_url)
|
||||
return NotificationTestResponse(success=success, message=message)
|
||||
|
||||
|
||||
# ── Admin Logs ─────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ def _paginate(total: int, page: int, page_size: int) -> dict:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/processing-runs",
|
||||
"",
|
||||
response_model=PaginatedProcessingRunsResponse,
|
||||
summary="List processing runs for the current user",
|
||||
)
|
||||
@@ -117,7 +117,7 @@ async def list_processing_runs(
|
||||
|
||||
|
||||
@router.get(
|
||||
"/processing-runs/{run_id}",
|
||||
"/{run_id}",
|
||||
response_model=ProcessingRunDetailResponse,
|
||||
summary="Get a single processing run",
|
||||
)
|
||||
@@ -160,7 +160,7 @@ async def get_processing_run(
|
||||
|
||||
|
||||
@router.get(
|
||||
"/processing-runs/{run_id}/logs",
|
||||
"/{run_id}/logs",
|
||||
response_model=PaginatedProcessingLogsResponse,
|
||||
summary="Get per-email logs for a processing run",
|
||||
)
|
||||
|
||||
@@ -7,6 +7,11 @@ Comprehensive task breakdown for repository improvements and production readines
|
||||
- [x] Rename entire project to **InboxConverge**: all user-visible strings, Docker container/image names, DB defaults, monitoring, and docs updated.
|
||||
- [x] Domain updated to `inboxconverge.com`; contact email defaults to `christian@inboxconverge.com`.
|
||||
- [x] New configurable env vars: `CONTACT_EMAIL`, `APP_URL`, `NEXT_PUBLIC_APP_NAME`.
|
||||
- [x] Fixed Black formatting failure in CI (`admin.py` reformatted).
|
||||
- [x] Fixed `/processing-runs` endpoint 404s caused by duplicate path prefix in `logs.py`.
|
||||
- [x] Added Semantic Release workflow (`release.yml`) for automatic versioning and GitHub Releases.
|
||||
- [x] Added `pyproject.toml` with `[tool.semantic_release]` configuration.
|
||||
- [x] Added GitOps auto-deployment step in `ci.yml` to update preprod k8s manifest in `k8s-cluster-state` repo.
|
||||
|
||||
## 🔴 Critical - Security (In Progress)
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=45", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "inboxconverge"
|
||||
dynamic = ["version"]
|
||||
description = "Multi-account email forwarding and processing service"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
license = {text = "MIT"}
|
||||
authors = [
|
||||
{name = "Christian Louis", email = "christianlouis@users.noreply.github.com"}
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/christianlouis/InboxConverge"
|
||||
Repository = "https://github.com/christianlouis/InboxConverge"
|
||||
Issues = "https://github.com/christianlouis/InboxConverge/issues"
|
||||
Changelog = "https://github.com/christianlouis/InboxConverge/blob/main/CHANGELOG.md"
|
||||
|
||||
[tool.semantic_release]
|
||||
version_source = "tag"
|
||||
commit_version_number = true
|
||||
tag_format = "v{version}"
|
||||
major_on_zero = false
|
||||
allow_zero_version = true
|
||||
|
||||
[tool.semantic_release.branches.main]
|
||||
match = "main"
|
||||
prerelease = false
|
||||
|
||||
[tool.semantic_release.changelog]
|
||||
mode = "update"
|
||||
exclude_commit_patterns = [
|
||||
"^chore\\(release\\):",
|
||||
"^Merge",
|
||||
"^Bump version",
|
||||
]
|
||||
|
||||
[tool.semantic_release.changelog.default_templates]
|
||||
changelog_file = "CHANGELOG.md"
|
||||
output_format = "md"
|
||||
|
||||
[tool.semantic_release.commit_parser_options]
|
||||
allowed_tags = [
|
||||
"feat",
|
||||
"fix",
|
||||
"docs",
|
||||
"style",
|
||||
"refactor",
|
||||
"perf",
|
||||
"test",
|
||||
"build",
|
||||
"ci",
|
||||
"chore",
|
||||
]
|
||||
minor_tags = ["feat"]
|
||||
patch_tags = ["fix", "perf"]
|
||||
default_bump_level = 0
|
||||
|
||||
[tool.semantic_release.remote]
|
||||
name = "origin"
|
||||
type = "github"
|
||||
ignore_token_for_push = false
|
||||
|
||||
[tool.semantic_release.remote.token]
|
||||
env = "GH_TOKEN"
|
||||
|
||||
[tool.semantic_release.publish]
|
||||
dist_glob_patterns = []
|
||||
upload_to_vcs_release = true
|
||||
upload_to_pypi = false
|
||||
upload_to_repository = false
|
||||
Reference in New Issue
Block a user