diff --git a/.github/workflows/ofl-ota-cronjob.yml b/.github/workflows/ofl-ota-cronjob.yml index 4b2db9ee94..e60e2b3971 100644 --- a/.github/workflows/ofl-ota-cronjob.yml +++ b/.github/workflows/ofl-ota-cronjob.yml @@ -11,6 +11,10 @@ name: Daily OFL OTA Update # workflow trusts and uses to bypass the FOLDER_MERGERS check for this trigger. That same explicit- # vendor-dispatch path is also what makes post_merge_profiles.yml call the OTA auto-publish API after # uploading - see post_merge_profiles.yml for both sides of that contract. +# +# If at least one branch was dispatched this run, a final step clears OFL's pending-publish +# table (POST /api/v1/ota/ofl/pending/clear) - the daily "published everything, reset" signal. +# That table is populated only by this pipeline's own auto-publish calls. on: schedule: @@ -42,11 +46,13 @@ jobs: run: git fetch origin '+refs/heads/*:refs/remotes/origin/*' - name: Scan branches and publish changed OFL profiles + id: scan shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail + published_any=false mapfile -t branches < <( gh api "repos/${{ github.repository }}/branches" --paginate --jq '.[].name' \ @@ -89,13 +95,48 @@ jobs: # Tolerate a per-branch failure (e.g. a pre-existing release branch # whose post_merge_profiles.yml predates the vendor/auto_publish # inputs) rather than aborting the whole scan under set -e. - if ! gh workflow run post_merge_profiles.yml \ + if gh workflow run post_merge_profiles.yml \ --repo "${{ github.repository }}" \ --ref "$branch" \ -f vendor="$VENDOR" -f auto_publish=true; then + published_any=true + else echo "::warning::failed to dispatch post_merge_profiles.yml for $branch - its post_merge_profiles.yml at this ref may predate the vendor/auto_publish inputs" fi fi echo "::endgroup::" done + + echo "published_any=$published_any" >> "$GITHUB_OUTPUT" + + - name: Clear OFL pending queue + # Only when this run actually kicked off at least one publish - the + # daily reset is scoped to today's real activity, not called on a day + # where every branch reported no changes. Note "published_any" reflects + # a successful DISPATCH, not a confirmed live publish: gh workflow run + # is fire-and-forget, so this workflow never learns whether the + # dispatched post_merge_profiles.yml run actually reached its own + # auto-publish call. Acceptable since the table is populated only by + # our own auto-publish calls, not by anything else. + if: steps.scan.outputs.published_any == 'true' + shell: bash + env: + OTA_API_BASE_URL: ${{ vars.OTA_API_BASE_URL }} + OTA_API_KEY: ${{ secrets.OFL_OTA_PUBLISH_KEY }} + run: | + set -euo pipefail + [ -n "$OTA_API_BASE_URL" ] || { echo "::error::vars.OTA_API_BASE_URL is not set"; exit 1; } + [ -n "$OTA_API_KEY" ] || { echo "::error::secrets.OFL_OTA_PUBLISH_KEY is not set"; exit 1; } + + resp_file="$RUNNER_TEMP/ota-pending-clear-response.json" + status="$(curl -sS -o "$resp_file" -w '%{http_code}' -X POST \ + "${OTA_API_BASE_URL%/}/api/v1/ota/ofl/pending/clear" \ + -H "Authorization: Bearer $OTA_API_KEY")" + body="$(cat "$resp_file")" + echo "$body" + + if [ "$status" != "200" ]; then + echo "::error::OTA pending-clear call failed with HTTP $status" + exit 1 + fi