diff --git a/.github/workflows/docker-build.ecr.yml b/.github/workflows/docker-build.ecr.yml index 0a819e12..ec4a36ef 100644 --- a/.github/workflows/docker-build.ecr.yml +++ b/.github/workflows/docker-build.ecr.yml @@ -33,6 +33,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - name: configure aws credentials uses: aws-actions/configure-aws-credentials@v4 @@ -46,6 +48,32 @@ jobs: run: | echo "timestamp=$(date +%s)" >> $GITHUB_OUTPUT echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + echo "sha_full=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT + + - name: Determine version and deployment context + id: version + run: | + REPO_URL="https://github.com/${{ github.repository }}" + + if [[ "${{ github.ref_type }}" == "tag" ]]; then + # Tag deployment - display version, link to release + echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT + echo "app_version=${{ github.ref_name }}" >> $GITHUB_OUTPUT + echo "app_version_url=${REPO_URL}/releases/tag/${{ github.ref_name }}" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + # PR deployment - display pr-XXX, link to PR commit + PR_NUMBER="${{ github.event.pull_request.number }}" + COMMIT_HASH="${{ steps.vars.outputs.sha_full }}" + echo "version=${PR_NUMBER}/merge-${COMMIT_HASH}" >> $GITHUB_OUTPUT + echo "app_version=pr-${PR_NUMBER}" >> $GITHUB_OUTPUT + echo "app_version_url=${REPO_URL}/pull/${PR_NUMBER}/commits/${COMMIT_HASH}" >> $GITHUB_OUTPUT + else + # Branch deployment - display branch name, link to commit + BRANCH_NAME="${{ github.ref_name }}" + COMMIT_HASH="${{ steps.vars.outputs.sha_full }}" + echo "app_version=${BRANCH_NAME}" >> $GITHUB_OUTPUT + echo "app_version_url=${REPO_URL}/commit/${COMMIT_HASH}" >> $GITHUB_OUTPUT + fi - name: Login to Amazon ECR id: login-ecr @@ -78,5 +106,9 @@ jobs: push: ${{ github.event_name != 'pull_request' || env.PUSH_FROM_PR == 'true' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-args: | + APP_REPOSITORY=https://github.com/${{ github.repository }} + APP_VERSION=${{ steps.version.outputs.app_version }} + APP_VERSION_URL=${{ steps.version.outputs.app_version_url }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/.github/workflows/docker-build.ghcr.yml b/.github/workflows/docker-build.ghcr.yml index 92398dee..0ed34055 100644 --- a/.github/workflows/docker-build.ghcr.yml +++ b/.github/workflows/docker-build.ghcr.yml @@ -44,12 +44,40 @@ jobs: egress-policy: audit - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - name: Set current timestamp id: vars run: | echo "timestamp=$(date +%s)" >> $GITHUB_OUTPUT echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + echo "sha_full=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT + + - name: Determine version and deployment context + id: version + run: | + REPO_URL="https://github.com/${{ github.repository }}" + + if [[ "${{ github.ref_type }}" == "tag" ]]; then + # Tag deployment - display version, link to release + echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT + echo "app_version=${{ github.ref_name }}" >> $GITHUB_OUTPUT + echo "app_version_url=${REPO_URL}/releases/tag/${{ github.ref_name }}" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + # PR deployment - display pr-XXX, link to PR commit + PR_NUMBER="${{ github.event.pull_request.number }}" + COMMIT_HASH="${{ steps.vars.outputs.sha_full }}" + echo "version=${PR_NUMBER}/merge-${COMMIT_HASH}" >> $GITHUB_OUTPUT + echo "app_version=pr-${PR_NUMBER}" >> $GITHUB_OUTPUT + echo "app_version_url=${REPO_URL}/pull/${PR_NUMBER}/commits/${COMMIT_HASH}" >> $GITHUB_OUTPUT + else + # Branch deployment - display branch name, link to commit + BRANCH_NAME="${{ github.ref_name }}" + COMMIT_HASH="${{ steps.vars.outputs.sha_full }}" + echo "app_version=${BRANCH_NAME}" >> $GITHUB_OUTPUT + echo "app_version_url=${REPO_URL}/commit/${COMMIT_HASH}" >> $GITHUB_OUTPUT + fi - name: Log in to the Container registry uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 @@ -87,6 +115,10 @@ jobs: push: ${{ github.event_name != 'pull_request' || env.PUSH_FROM_PR == 'true' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-args: | + APP_REPOSITORY=https://github.com/${{ github.repository }} + APP_VERSION=${{ steps.version.outputs.app_version }} + APP_VERSION_URL=${{ steps.version.outputs.app_version_url }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile index d686922e..08fdef45 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,9 +20,15 @@ FROM python:3.13.5-slim@sha256:4c2cf9917bd1cbacc5e9b07320025bdb7cdf2df7b0ceaccb5 ARG UID=1000 ARG GID=1000 +ARG APP_REPOSITORY=https://github.com/coderamp-labs/gitingest +ARG APP_VERSION=unknown +ARG APP_VERSION_URL=https://github.com/coderamp-labs/gitingest ENV PYTHONUNBUFFERED=1 \ - PYTHONDONTWRITEBYTECODE=1 + PYTHONDONTWRITEBYTECODE=1 \ + APP_REPOSITORY=${APP_REPOSITORY} \ + APP_VERSION=${APP_VERSION} \ + APP_VERSION_URL=${APP_VERSION_URL} RUN set -eux; \ apt-get update; \ diff --git a/src/server/main.py b/src/server/main.py index d973c387..f66f674f 100644 --- a/src/server/main.py +++ b/src/server/main.py @@ -18,7 +18,7 @@ from gitingest.utils.logging_config import get_logger from server.metrics_server import start_metrics_server from server.routers import dynamic, index, ingest -from server.server_config import templates +from server.server_config import get_version_info, templates from server.server_utils import limiter, rate_limit_exception_handler # Load environment variables from .env file @@ -169,7 +169,9 @@ async def custom_swagger_ui(request: Request) -> HTMLResponse: - **HTMLResponse**: Custom Swagger UI documentation page """ - return templates.TemplateResponse("swagger_ui.jinja", {"request": request}) + context = {"request": request} + context.update(get_version_info()) + return templates.TemplateResponse("swagger_ui.jinja", context) @app.get("/api", include_in_schema=True) diff --git a/src/server/routers/dynamic.py b/src/server/routers/dynamic.py index 93b9d68b..49fdf1b9 100644 --- a/src/server/routers/dynamic.py +++ b/src/server/routers/dynamic.py @@ -3,7 +3,7 @@ from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse -from server.server_config import templates +from server.server_config import get_version_info, templates router = APIRouter() @@ -29,11 +29,11 @@ async def catch_all(request: Request, full_path: str) -> HTMLResponse: and other default parameters such as file size. """ - return templates.TemplateResponse( - "git.jinja", - { - "request": request, - "repo_url": full_path, - "default_max_file_size": 243, - }, - ) + context = { + "request": request, + "repo_url": full_path, + "default_max_file_size": 243, + } + context.update(get_version_info()) + + return templates.TemplateResponse("git.jinja", context) diff --git a/src/server/routers/index.py b/src/server/routers/index.py index af4abd51..e8dfdfdb 100644 --- a/src/server/routers/index.py +++ b/src/server/routers/index.py @@ -3,7 +3,7 @@ from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse -from server.server_config import EXAMPLE_REPOS, templates +from server.server_config import EXAMPLE_REPOS, get_version_info, templates router = APIRouter() @@ -27,11 +27,11 @@ async def home(request: Request) -> HTMLResponse: and other default parameters such as file size. """ - return templates.TemplateResponse( - "index.jinja", - { - "request": request, - "examples": EXAMPLE_REPOS, - "default_max_file_size": 243, - }, - ) + context = { + "request": request, + "examples": EXAMPLE_REPOS, + "default_max_file_size": 243, + } + context.update(get_version_info()) + + return templates.TemplateResponse("index.jinja", context) diff --git a/src/server/server_config.py b/src/server/server_config.py index d333e6a1..56b5eb19 100644 --- a/src/server/server_config.py +++ b/src/server/server_config.py @@ -2,6 +2,7 @@ from __future__ import annotations +import os from pathlib import Path from fastapi.templating import Jinja2Templates @@ -21,6 +22,35 @@ ] +# Version and repository configuration +APP_REPOSITORY = os.getenv("APP_REPOSITORY", "https://github.com/coderamp-labs/gitingest") +APP_VERSION = os.getenv("APP_VERSION", "unknown") +APP_VERSION_URL = os.getenv("APP_VERSION_URL", "https://github.com/coderamp-labs/gitingest") + + +def get_version_info() -> dict[str, str]: + """Get version information including display version and link. + + Returns + ------- + dict[str, str] + Dictionary containing 'version' and 'version_link' keys. + + """ + # Use pre-computed values from GitHub Actions + display_version = APP_VERSION + version_link = APP_VERSION_URL + + # Fallback to repository root if no URL is provided + if version_link == APP_REPOSITORY or not version_link: + version_link = f"{APP_REPOSITORY.rstrip('/')}/tree/main" + + return { + "version": display_version, + "version_link": version_link, + } + + # Use absolute path to templates directory templates_dir = Path(__file__).parent / "templates" templates = Jinja2Templates(directory=templates_dir) diff --git a/src/server/templates/components/footer.jinja b/src/server/templates/components/footer.jinja index 9784dfeb..03900e3e 100644 --- a/src/server/templates/components/footer.jinja +++ b/src/server/templates/components/footer.jinja @@ -1,7 +1,7 @@ {% from 'components/_macros.jinja' import footer_icon_link %}