From 768895a07b24b5ff3bd69e48f5991fa1fdababfa Mon Sep 17 00:00:00 2001 From: Nicolas Iragne Date: Sun, 3 Aug 2025 10:31:49 +0200 Subject: [PATCH 01/16] chore: update fastapi link (#486) --- src/server/server_config.py | 2 +- tests/query_parser/test_git_host_agnostic.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/server_config.py b/src/server/server_config.py index 6918bf2..d333e6a 100644 --- a/src/server/server_config.py +++ b/src/server/server_config.py @@ -14,7 +14,7 @@ MAX_FILE_SIZE_KB: int = 100 * 1024 # 100 mb EXAMPLE_REPOS: list[dict[str, str]] = [ {"name": "Gitingest", "url": "https://github.com/coderamp-labs/gitingest"}, - {"name": "FastAPI", "url": "https://github.com/tiangolo/fastapi"}, + {"name": "FastAPI", "url": "https://github.com/fastapi/fastapi"}, {"name": "Flask", "url": "https://github.com/pallets/flask"}, {"name": "Excalidraw", "url": "https://github.com/excalidraw/excalidraw"}, {"name": "ApiAnalytics", "url": "https://github.com/tom-draper/api-analytics"}, diff --git a/tests/query_parser/test_git_host_agnostic.py b/tests/query_parser/test_git_host_agnostic.py index ce95aa9..9a67201 100644 --- a/tests/query_parser/test_git_host_agnostic.py +++ b/tests/query_parser/test_git_host_agnostic.py @@ -14,7 +14,7 @@ from gitingest.utils.query_parser_utils import KNOWN_GIT_HOSTS, _is_valid_git_co # Repository matrix: (host, user, repo) _REPOS: list[tuple[str, str, str]] = [ - ("github.com", "tiangolo", "fastapi"), + ("github.com", "fastapi", "fastapi"), ("gitlab.com", "gitlab-org", "gitlab-runner"), ("bitbucket.org", "na-dna", "llm-knowledge-share"), ("gitea.com", "xorm", "xorm"), From 6ece06c1e5f00187a81ec9fce21dae76ffdd94d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 11:57:00 +0200 Subject: [PATCH 02/16] chore: Configure Renovate (#489) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/dependabot.yml | 22 ---------------------- renovate.json | 6 ++++++ 2 files changed, 6 insertions(+), 22 deletions(-) delete mode 100644 .github/dependabot.yml create mode 100644 renovate.json diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 73efd68..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,22 +0,0 @@ -version: 2 -updates: - # ─── Python (pip) ───────────────────────────── - - package-ecosystem: "pip" - directory: "/" - schedule: { interval: "weekly" } - labels: [ "dependencies", "pip" ] - groups: # Group patches & minors from dev-only tools - dev-py: - dependency-type: "development" - update-types: ["minor", "patch"] - - # ─── GitHub Actions ─────────────────────────── - - package-ecosystem: "github-actions" - directory: "/" - schedule: { interval: "weekly" } - labels: [ "dependencies", "gh-actions" ] - - - package-ecosystem: docker - directory: / - schedule: - interval: daily diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} From bea6d25190c5a183ef7250746e71fe3a8ea1274c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 12:01:36 +0200 Subject: [PATCH 03/16] chore(deps): update ossf/scorecard-action digest to f35c645 (#491) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 8025b93..da40afd 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -32,7 +32,7 @@ jobs: persist-credentials: false - name: Run Scorecard - uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde + uses: ossf/scorecard-action@f35c64557cf912815708bb1126d9948f3e459487 with: results_file: results.sarif results_format: sarif From 15949d3df578623e9b8083efd3f8d6163fa30bde Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 18:09:52 +0200 Subject: [PATCH 04/16] chore(deps): update actions/checkout digest to 8edcb1b (#490) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index da40afd..43250d4 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -27,7 +27,7 @@ jobs: egress-policy: audit - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 with: persist-credentials: false From b43aa3ecbcee38ab4518d5a474a3348ac517e2e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 18:10:15 +0200 Subject: [PATCH 05/16] chore(deps): update docker/login-action action to v3.5.0 (#493) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docker-build.ghcr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.ghcr.yml b/.github/workflows/docker-build.ghcr.yml index de72fba..28323f9 100644 --- a/.github/workflows/docker-build.ghcr.yml +++ b/.github/workflows/docker-build.ghcr.yml @@ -52,7 +52,7 @@ jobs: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - name: Log in to the Container registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} From ca117481e4ab209120e8f9bae558d8c12f919d33 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 18:10:31 +0200 Subject: [PATCH 06/16] chore(deps): update docker/metadata-action action to v5.8.0 (#494) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docker-build.ghcr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.ghcr.yml b/.github/workflows/docker-build.ghcr.yml index 28323f9..92398de 100644 --- a/.github/workflows/docker-build.ghcr.yml +++ b/.github/workflows/docker-build.ghcr.yml @@ -60,7 +60,7 @@ jobs: - name: Docker Meta id: meta - uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 + uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} From 867c2d904e57ef2b329ba863661062cc92be39c9 Mon Sep 17 00:00:00 2001 From: Mickael Date: Tue, 5 Aug 2025 18:20:13 +0200 Subject: [PATCH 07/16] feat(web): add version info display (#483) Co-authored-by: Nicolas IRAGNE --- .github/workflows/docker-build.ecr.yml | 32 ++++++++++++++++++++ .github/workflows/docker-build.ghcr.yml | 32 ++++++++++++++++++++ Dockerfile | 8 ++++- src/server/main.py | 6 ++-- src/server/routers/dynamic.py | 18 +++++------ src/server/routers/index.py | 18 +++++------ src/server/server_config.py | 30 ++++++++++++++++++ src/server/templates/components/footer.jinja | 14 ++++++++- 8 files changed, 136 insertions(+), 22 deletions(-) diff --git a/.github/workflows/docker-build.ecr.yml b/.github/workflows/docker-build.ecr.yml index 0a819e1..ec4a36e 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 92398de..0ed3405 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 d686922..08fdef4 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 d973c38..f66f674 100644 --- a/src/server/main.py +++ b/src/server/main.py @@ -18,7 +18,7 @@ from starlette.middleware.trustedhost import TrustedHostMiddleware 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 93b9d68..49fdf1b 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 af4abd5..e8dfdfd 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 d333e6a..56b5eb1 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 @@ EXAMPLE_REPOS: list[dict[str, str]] = [ ] +# 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 9784dfe..03900e3 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 %}