From f545422dc8e05da802fb0b7af7492bade92cae8a Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 9 Mar 2026 21:36:24 +0000 Subject: [PATCH 1/8] Update ghcr.io/astral-sh/uv Docker tag to v0.10 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 73b1053c..c15b088e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM eclipse-temurin:21.0.9_10-jre-noble # install astral uv -COPY --from=ghcr.io/astral-sh/uv:0.8 /uv /usr/local/bin/ +COPY --from=ghcr.io/astral-sh/uv:0.10 /uv /usr/local/bin/ ARG DEBIAN_FRONTEND=noninteractive ARG PHOTON_VERSION From ebd0baa3a105bbfc53afc96904690562f1a02626 Mon Sep 17 00:00:00 2001 From: Robin Tuszik Date: Mon, 9 Mar 2026 23:42:08 +0100 Subject: [PATCH 2/8] further renovate config --- renovate.json | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/renovate.json b/renovate.json index aa272750..871d7924 100644 --- a/renovate.json +++ b/renovate.json @@ -1,14 +1,20 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended", - "helpers:pinGitHubActionDigests", - ":configMigration", - ":pinDevDependencies", - "abandonments:recommended", - ":enablePreCommit" - ], - "baseBranchPatterns": [ - "dev" - ] + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:best-practices", + ":enablePreCommit" + ], + "baseBranchPatterns": [ + "dev" + ], + "packageRules": [ + { + "matchUpdateTypes": [ + "minor", + "patch" + ], + "matchCurrentVersion": "!/^0/", + "automerge": true + } + ] } From f86dd131ca48d8e8275ed5fe9a7186a83f26d279 Mon Sep 17 00:00:00 2001 From: Robin Tuszik Date: Mon, 9 Mar 2026 22:48:40 +0100 Subject: [PATCH 3/8] release-drafter formatting --- .github/workflows/release-drafter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 8b703222..d480749a 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -32,7 +32,7 @@ jobs: PHOTON_VERSION=$(tr -d '[:space:]' < .last_release) { printf '%s' "$DRAFT_BODY" - printf '\n\n---\n **Upstream Photon release notes (%s):** https://github.com/komoot/photon/releases/tag/%s\n' \ + printf '\n\n---\n **[Photon release notes](https://github.com/komoot/photon/releases/tag/%s) (%s):** \n' \ "$PHOTON_VERSION" "$PHOTON_VERSION" } > /tmp/new_body.txt gh api "repos/${{ github.repository }}/releases/${{ steps.release-drafter.outputs.id }}" \ From fe0823edf17844fad965c707e14c51e81c6c35c1 Mon Sep 17 00:00:00 2001 From: Robin Tuszik Date: Fri, 27 Mar 2026 10:02:09 +0100 Subject: [PATCH 4/8] move from prek.toml to .pre-commit-config.yml for compatibility --- .pre-commit-config.yml | 21 +++++++++++++++++++++ prek.toml | 20 -------------------- 2 files changed, 21 insertions(+), 20 deletions(-) create mode 100644 .pre-commit-config.yml delete mode 100644 prek.toml diff --git a/.pre-commit-config.yml b/.pre-commit-config.yml new file mode 100644 index 00000000..c0cb6aa8 --- /dev/null +++ b/.pre-commit-config.yml @@ -0,0 +1,21 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + - id: check-yaml + - id: end-of-file-fixer + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.15.4 + hooks: + - id: ruff-check + args: [--fix] + files: "\\.py$" + - id: ruff-format + files: "\\.py$" + + - repo: https://github.com/rhysd/actionlint + rev: v1.7.11 + hooks: + - id: actionlint diff --git a/prek.toml b/prek.toml deleted file mode 100644 index 0016349f..00000000 --- a/prek.toml +++ /dev/null @@ -1,20 +0,0 @@ -[[repos]] -repo = "https://github.com/pre-commit/pre-commit-hooks" -rev = "v6.0.0" -hooks = [ - { id = "check-yaml" }, - { id = "end-of-file-fixer" }, -] - -[[repos]] -repo = "https://github.com/rhysd/actionlint" -rev = "v1.7.11" -hooks = [{ id = "actionlint" }] - -[[repos]] -repo = "https://github.com/astral-sh/ruff-pre-commit" -rev = "v0.15.0" -hooks = [ - { id = "ruff-check", args = ["--fix"], types_or = ["python", "pyi"] }, - { id = "ruff-format", types_or = ["python", "pyi"] }, -] From 2dfcb1912a2a9f34f3001de41f2cd81f2980185f Mon Sep 17 00:00:00 2001 From: Robin Tuszik Date: Fri, 27 Mar 2026 10:02:42 +0100 Subject: [PATCH 5/8] renovate: enhance renovate config with labels, grouping, and rules --- renovate.json | 60 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/renovate.json b/renovate.json index 871d7924..53e8d4a0 100644 --- a/renovate.json +++ b/renovate.json @@ -1,20 +1,58 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:best-practices", - ":enablePreCommit" - ], - "baseBranchPatterns": [ - "dev" - ], + "extends": ["config:best-practices", ":enablePreCommit"], + "prConcurrentLimit": 0, + "prCreation": "not-pending", + "rebaseWhen": "behind-base-branch", + "labels": ["renovate"], + "baseBranchPatterns": ["dev"], + "useBaseBranchConfig": "merge", + "internalChecksFilter": "strict", + "minimumReleaseAge": "3 days", "packageRules": [ { - "matchUpdateTypes": [ - "minor", - "patch" - ], + "matchUpdateTypes": ["patch"], + "addLabels": ["dependencies", "patch"], + "minimumReleaseAge": "3 days" + }, + { + "matchUpdateTypes": ["minor"], + "addLabels": ["dependencies", "minor"], + "minimumReleaseAge": "3 days" + }, + { + "matchUpdateTypes": ["major"], + "addLabels": ["dependencies", "major"], + "minimumReleaseAge": "7 days" + }, + { + "matchDepTypes": ["devDependencies", "dev"], + "matchUpdateTypes": ["minor", "patch"], "matchCurrentVersion": "!/^0/", "automerge": true + }, + { + "matchPackageNames": ["ruff", "astral-sh/ruff-pre-commit"], + "groupName": "ruff" + }, + { + "groupName": "Python Version", + "matchPackageNames": ["python"], + "matchManagers": ["custom.regex", "pyenv", "pep621"] + } + ], + + "customManagers": [ + { + // updates ruff target version + "customType": "regex", + "managerFilePatterns": ["/^pyproject\\.toml$/"], + "matchStrings": ["target-version = \"py3(?\\d+)\""], + "currentValueTemplate": "3.{{{minor}}}", + "autoReplaceStringTemplate": "target-version = \"py3{{{replace '.' '' newValue}}}\"", + "depNameTemplate": "python", + "datasourceTemplate": "python-version", + "versioningTemplate": "python" } ] } From 2c008ec28b2c86ebdab6328e4dd6242e9e848c55 Mon Sep 17 00:00:00 2001 From: Robin Tuszik Date: Fri, 27 Mar 2026 10:03:15 +0100 Subject: [PATCH 6/8] fix clashing rules in ruff config --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 86576668..dcfd348c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,6 @@ line-length = 120 ignore = [ "ANN", # flake8-annotations "COM", # flake8-commas - "C90", # mccabe complexity "DJ", # django "EXE", # flake8-executable "BLE", # blind except From 1192d21b5fa4710d3b484ae3d7be4ef67b67f6d3 Mon Sep 17 00:00:00 2001 From: Robin Tuszik Date: Thu, 2 Apr 2026 14:10:36 +0200 Subject: [PATCH 7/8] ci: improve workflow security and use env vars --- .github/workflows/build-and-push.yml | 27 ++++++++++++++++----------- .github/workflows/check-releases.yml | 20 ++++++++++++-------- .github/workflows/full-test.yml | 8 ++++++-- .github/workflows/lint.yml | 8 ++++++++ .github/workflows/pytest.yml | 2 ++ .github/workflows/release-drafter.yml | 5 ++++- 6 files changed, 48 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 9c3d37fe..3e88a38c 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -25,6 +25,7 @@ jobs: uses: actions/checkout@v6 with: ref: ${{ github.ref }} + persist-credentials: false - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -54,7 +55,7 @@ jobs: fi echo "Read photon version from .last_release: $PHOTON_VERSION" else - PHOTON_VERSION="${{ github.event.inputs.photon_version }}" + PHOTON_VERSION="${GITHUB_EVENT_INPUTS_PHOTON_VERSION}" if [[ -z "$PHOTON_VERSION" ]]; then echo "Error: PHOTON_VERSION must be provided when .last_release file is missing" exit 1 @@ -62,10 +63,10 @@ jobs: fi if [ "${{ github.event_name }}" == "release" ]; then - CONTAINER_VERSION="${{ github.event.release.tag_name }}" + CONTAINER_VERSION="${GITHUB_EVENT_RELEASE_TAG_NAME}" CONTAINER_VERSION="${CONTAINER_VERSION#v}" IS_PRERELEASE="${{ github.event.release.prerelease }}" - elif [ "${{ github.event_name }}" == "push" ] && [ "${{ github.ref }}" == "refs/heads/dev" ]; then + elif [ "${{ github.event_name }}" == "push" ] && [ "${GITHUB_REF}" == "refs/heads/dev" ]; then SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) CONTAINER_VERSION="dev-${SHORT_SHA}" IS_PRERELEASE="true" @@ -73,7 +74,7 @@ jobs: CONTAINER_VERSION="pr-${{ github.event.pull_request.number }}" IS_PRERELEASE="true" else - CONTAINER_VERSION="${{ github.event.inputs.container_version }}" + CONTAINER_VERSION="${GITHUB_EVENT_INPUTS_CONTAINER_VERSION}" CONTAINER_VERSION="${CONTAINER_VERSION#v}" if [[ "$CONTAINER_VERSION" == *"-beta"* ]]; then @@ -90,12 +91,16 @@ jobs: echo "Container Version: $CONTAINER_VERSION" echo "Photon Version: $PHOTON_VERSION" echo "Is Prerelease: $IS_PRERELEASE" + env: + GITHUB_EVENT_INPUTS_PHOTON_VERSION: ${{ github.event.inputs.photon_version }} + GITHUB_EVENT_RELEASE_TAG_NAME: ${{ github.event.release.tag_name }} + GITHUB_EVENT_INPUTS_CONTAINER_VERSION: ${{ github.event.inputs.container_version }} - name: Generate Docker tags with semver support id: generate_tags run: | - CONTAINER_VERSION="${{ env.CONTAINER_VERSION }}" - IS_PRERELEASE="${{ env.IS_PRERELEASE }}" + CONTAINER_VERSION="${CONTAINER_VERSION}" + IS_PRERELEASE="${IS_PRERELEASE}" REPO_NAME="${{ github.repository }}" DOCKERHUB_REPO="${REPO_NAME,,}" @@ -103,7 +108,7 @@ jobs: TAGS="$DOCKERHUB_REPO:$CONTAINER_VERSION,$GHCR_REPO:$CONTAINER_VERSION" - if [ "${{ github.event_name }}" == "push" ] && [ "${{ github.ref }}" == "refs/heads/dev" ]; then + if [ "${{ github.event_name }}" == "push" ] && [ "${GITHUB_REF}" == "refs/heads/dev" ]; then TAGS="$TAGS,$DOCKERHUB_REPO:dev,$GHCR_REPO:dev" elif [ "$IS_PRERELEASE" == "true" ]; then TAGS="$TAGS,$DOCKERHUB_REPO:beta,$GHCR_REPO:beta" @@ -143,7 +148,7 @@ jobs: run: | echo "## Docker Build Summary" >> $GITHUB_STEP_SUMMARY echo "- **Event:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY - echo "- **Container Version:** ${{ env.CONTAINER_VERSION }}" >> $GITHUB_STEP_SUMMARY - echo "- **Photon Version:** ${{ env.PHOTON_VERSION }}" >> $GITHUB_STEP_SUMMARY - echo "- **Is Prerelease:** ${{ env.IS_PRERELEASE }}" >> $GITHUB_STEP_SUMMARY - echo "- **Tags:** ${{ env.DOCKER_TAGS }}" >> $GITHUB_STEP_SUMMARY + echo "- **Container Version:** ${CONTAINER_VERSION}" >> $GITHUB_STEP_SUMMARY + echo "- **Photon Version:** ${PHOTON_VERSION}" >> $GITHUB_STEP_SUMMARY + echo "- **Is Prerelease:** ${IS_PRERELEASE}" >> $GITHUB_STEP_SUMMARY + echo "- **Tags:** ${DOCKER_TAGS}" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/check-releases.yml b/.github/workflows/check-releases.yml index 0321efbd..69f38664 100644 --- a/.github/workflows/check-releases.yml +++ b/.github/workflows/check-releases.yml @@ -15,6 +15,8 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v6 + with: + persist-credentials: false - name: Check for new Photon release id: check_release @@ -43,26 +45,28 @@ jobs: - name: Determine if update is needed id: prepare_update run: | - if [[ -n "${{ env.latest_release_version }}" && "${{ env.latest_release_version }}" != "${{ env.last_processed_version }}" ]]; then - echo "New version found: ${{ env.latest_release_version }}. (Previous: ${{ env.last_processed_version }})" + if [[ -n "${LATEST_RELEASE_VERSION}" && "${LATEST_RELEASE_VERSION}" != "${LAST_PROCESSED_VERSION}" ]]; then + echo "New version found: ${LATEST_RELEASE_VERSION}. (Previous: ${LAST_PROCESSED_VERSION})" { echo "update_needed=true" - echo "new_version=${{ env.latest_release_version }}" - echo "new_branch_name=update-photon-${{ env.latest_release_version }}" + echo "new_version=${LATEST_RELEASE_VERSION}" + echo "new_branch_name=update-photon-${LATEST_RELEASE_VERSION}" } >> "$GITHUB_OUTPUT" else - echo "No new Photon release detected or version is already up-to-date. Latest fetched: '${{ env.latest_release_version }}', last processed: '${{ env.last_processed_version }}'." + echo "No new Photon release detected or version is already up-to-date. Latest fetched: '${LATEST_RELEASE_VERSION}', last processed: '${LAST_PROCESSED_VERSION}'." { echo "update_needed=false" - echo "new_version=${{ env.last_processed_version }}" + echo "new_version=${LAST_PROCESSED_VERSION}" } >> "$GITHUB_OUTPUT" fi - name: Update release file(s) locally if: steps.prepare_update.outputs.update_needed == 'true' run: | - echo "Updating .last_release to ${{ steps.prepare_update.outputs.new_version }}" - echo "${{ steps.prepare_update.outputs.new_version }}" > .last_release + echo "Updating .last_release to ${STEPS_PREPARE_UPDATE_OUTPUTS_NEW_VERSION}" + echo "${STEPS_PREPARE_UPDATE_OUTPUTS_NEW_VERSION}" > .last_release + env: + STEPS_PREPARE_UPDATE_OUTPUTS_NEW_VERSION: ${{ steps.prepare_update.outputs.new_version }} - name: Create Pull Request if: steps.prepare_update.outputs.update_needed == 'true' diff --git a/.github/workflows/full-test.yml b/.github/workflows/full-test.yml index 50fa2f45..e147717e 100644 --- a/.github/workflows/full-test.yml +++ b/.github/workflows/full-test.yml @@ -19,6 +19,8 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -98,5 +100,7 @@ jobs: run: | echo "## Container Test Summary" >> $GITHUB_STEP_SUMMARY echo "- **PR Number:** ${{ github.event.pull_request.number }}" >> $GITHUB_STEP_SUMMARY - echo "- **Photon Version:** ${{ env.PHOTON_VERSION }}" >> $GITHUB_STEP_SUMMARY - echo "- **Status:** ${{ job.status }}" >> $GITHUB_STEP_SUMMARY + echo "- **Photon Version:** ${PHOTON_VERSION}" >> $GITHUB_STEP_SUMMARY + echo "- **Status:** ${JOB_STATUS}" >> $GITHUB_STEP_SUMMARY + env: + JOB_STATUS: ${{ job.status }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0b255bf9..a9b6ae1c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,6 +12,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: "Set up Python" uses: actions/setup-python@v6 with: @@ -36,6 +38,8 @@ jobs: needs: setup steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: "Set up Python" uses: actions/setup-python@v6 with: @@ -63,6 +67,8 @@ jobs: needs: setup steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: "Set up Python" uses: actions/setup-python@v6 with: @@ -87,6 +93,8 @@ jobs: needs: setup steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: "Set up Python" uses: actions/setup-python@v6 with: diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index e2da5265..92750cfa 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -16,6 +16,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v6 diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index d480749a..4bd49cc4 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -16,6 +16,8 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v6 + with: + persist-credentials: false - name: Run Release Drafter id: release-drafter @@ -28,6 +30,7 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} DRAFT_BODY: ${{ steps.release-drafter.outputs.body }} + STEPS_RELEASE_DRAFTER_OUTPUTS_ID: ${{ steps.release-drafter.outputs.id }} run: | PHOTON_VERSION=$(tr -d '[:space:]' < .last_release) { @@ -35,6 +38,6 @@ jobs: printf '\n\n---\n **[Photon release notes](https://github.com/komoot/photon/releases/tag/%s) (%s):** \n' \ "$PHOTON_VERSION" "$PHOTON_VERSION" } > /tmp/new_body.txt - gh api "repos/${{ github.repository }}/releases/${{ steps.release-drafter.outputs.id }}" \ + gh api "repos/${{ github.repository }}/releases/${STEPS_RELEASE_DRAFTER_OUTPUTS_ID}" \ --method PATCH \ --field body=@/tmp/new_body.txt From 1cc4c23dbfed5fc9926c1d47f9924827d1ba6d06 Mon Sep 17 00:00:00 2001 From: aaronspruit Date: Fri, 3 Apr 2026 12:21:40 -0700 Subject: [PATCH 8/8] fix: check if update is due based on UPDATE_INTERVAL daily --- src/process_manager.py | 61 +++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/src/process_manager.py b/src/process_manager.py index 392beb06..700afa3a 100644 --- a/src/process_manager.py +++ b/src/process_manager.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import datetime import os import shlex import signal @@ -10,7 +11,6 @@ import psutil import requests -import schedule from requests.exceptions import RequestException from src.check_remote import compare_mtime @@ -252,35 +252,52 @@ def run_update(self): self.state = AppState.RUNNING + def _parse_interval(self, interval: str) -> datetime.timedelta: + interval = interval.lower() + value = int(interval[:-1]) + unit = interval[-1] + if unit == "d": + return datetime.timedelta(days=value) + if unit == "h": + return datetime.timedelta(hours=value) + if unit == "m": + return datetime.timedelta(minutes=value) + logger.warning(f"Invalid UPDATE_INTERVAL format: {interval}, defaulting to 1 day") + return datetime.timedelta(days=1) + + def _is_update_due(self) -> bool: + marker_file = os.path.join(config.DATA_DIR, ".photon-index-updated") + if not os.path.exists(marker_file): + logger.info("No marker file found, update is due") + return True + + marker_time = datetime.datetime.fromtimestamp(os.path.getmtime(marker_file)) + now = datetime.datetime.now() + elapsed = now - marker_time + interval = self._parse_interval(config.UPDATE_INTERVAL) + + if elapsed < interval: + remaining = interval - elapsed + logger.info(f"Last update was {elapsed} ago, next check in {remaining}, skipping") + return False + + logger.info(f"Last update was {elapsed} ago (interval: {interval}), update due") + return True + def schedule_updates(self): if config.UPDATE_STRATEGY == "DISABLED": logger.info("Updates disabled, not scheduling") return - interval = config.UPDATE_INTERVAL.lower() - - if interval.endswith("d"): - days = int(interval[:-1]) - schedule.every(days).days.do(self.run_update) - logger.info(f"Scheduling updates every {days} days") - elif interval.endswith("h"): - hours = int(interval[:-1]) - schedule.every(hours).hours.do(self.run_update) - logger.info(f"Scheduling updates every {hours} hours") - elif interval.endswith("m"): - minutes = int(interval[:-1]) - schedule.every(minutes).minutes.do(self.run_update) - logger.info(f"Scheduling updates every {minutes} minutes") - else: - logger.warning(f"Invalid UPDATE_INTERVAL format: {interval}, defaulting to daily") - schedule.every().day.do(self.run_update) + logger.info(f"Scheduling daily update checks (update interval: {config.UPDATE_INTERVAL})") - def scheduler_loop(): + def update_loop(): while not self.should_exit: - schedule.run_pending() - time.sleep(1) + if self._is_update_due(): + self.run_update() + time.sleep(86400) - thread = threading.Thread(target=scheduler_loop, daemon=True) + thread = threading.Thread(target=update_loop, daemon=True) thread.start() def monitor_photon(self):