-
Notifications
You must be signed in to change notification settings - Fork 414
ci: schedule model metadata upkeep and check the snapshot against upstream #4460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
5d9f01c
feat(core): represent video and pdf model modalities
Astro-Han 5488f7c
refactor(core): drop the unread ModelMetadata.docsUrl
Astro-Han 6ce0f8a
feat(scripts): report models.dev snapshot drift against upstream
Astro-Han e2b5fcd
feat(scripts): cap what --accept-upstream-removals may acknowledge
Astro-Han 14a6a16
ci: refresh the model metadata snapshot weekly into a review pull req…
Astro-Han 28b9414
chore(model-metadata): refresh the models.dev snapshot
Astro-Han e8a95e1
refactor(core): give the model modality set one owner
Astro-Han 3b9a256
refactor(scripts): let one projector answer what a refresh changed
Astro-Han b9e9bbb
fix(ci): let the scheduled refresh reach the pull request it exists t…
Astro-Han File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| # Licensed to the Apache Software Foundation (ASF) under one | ||
| # or more contributor license agreements. See the NOTICE file | ||
| # distributed with this work for additional information | ||
| # regarding copyright ownership. The ASF licenses this file | ||
| # to you under the Apache License, Version 2.0 (the | ||
| # "License"); you may not use this file except in compliance | ||
| # with the License. You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, | ||
| # software distributed under the License is distributed on an | ||
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| # KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations | ||
| # under the License. | ||
|
|
||
| name: Model metadata upkeep | ||
|
|
||
| on: | ||
| schedule: | ||
| # Weekly, offset from the hour to reduce peak-time scheduling delays. The | ||
| # snapshot is a build input a human reviews, so a nightly cadence would | ||
| # only stack five near-identical pull requests against one week of upstream | ||
| # movement, on runners the whole foundation shares. | ||
| - cron: '41 6 * * 1' | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: model-metadata-upkeep | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| refresh: | ||
| # A fork inherits the schedule but owns neither the branch this pushes nor | ||
| # the pull request it opens. | ||
| if: github.repository == 'apache/maka' | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| steps: | ||
| - name: Check out the repository | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Set up Node.js | ||
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | ||
| with: | ||
| node-version: '24' | ||
| cache: npm | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: Report snapshot drift against models.dev | ||
| # Exit 2 is "upstream moved", which is the expected outcome and the | ||
| # reason this step exists. Any other non-zero status is the command | ||
| # itself failing, and the job stops on it. | ||
| run: | | ||
| npm run --silent check:model-metadata-drift > "$RUNNER_TEMP/drift.txt" || { | ||
| status=$? | ||
| cat "$RUNNER_TEMP/drift.txt" | ||
| [ "$status" -eq 2 ] || exit "$status" | ||
| } | ||
|
|
||
| - name: Publish the drift report | ||
| run: | | ||
| { | ||
| echo '### models.dev drift' | ||
| echo '' | ||
| echo '```text' | ||
| cat "$RUNNER_TEMP/drift.txt" | ||
| echo '```' | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| # --accept-upstream-removals, because the review seat this job is built | ||
| # around is the draft pull request below. A person still inspects every | ||
| # removal and still decides, in the diff, with the drift report in the | ||
| # body; refusing here would only make the job red every week, since it | ||
| # cannot rerun itself the way the acknowledgement asks a human to. | ||
| - name: Refresh the snapshot from models.dev | ||
| run: npm run refresh:model-metadata -- --accept-upstream-removals | ||
|
|
||
| - name: Verify the regenerated outputs | ||
| run: npm run check:model-metadata | ||
|
|
||
| - name: Detect a snapshot change | ||
| id: change | ||
| run: | | ||
| if git diff --quiet -- scripts/model-metadata/models-dev-api.snapshot.json; then | ||
| echo 'changed=false' >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo 'changed=true' >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| - name: Open the review pull request | ||
| if: steps.change.outputs.changed == 'true' | ||
| env: | ||
| BRANCH: automation/model-metadata-refresh | ||
| GH_TOKEN: ${{ github.token }} | ||
| TITLE: 'chore(model-metadata): refresh the models.dev snapshot' | ||
| run: | | ||
| { | ||
| echo '## Summary' | ||
| echo '' | ||
| echo 'Scheduled `refresh:model-metadata` run. The snapshot is the build' | ||
| echo 'input for the bundled model catalog; this only moves it to what' | ||
| echo 'models.dev serves today.' | ||
| echo '' | ||
| echo 'Refs #4398' | ||
| echo '' | ||
| echo '## Verification' | ||
| echo '' | ||
| echo 'The workflow ran `refresh:model-metadata` and `check:model-metadata`' | ||
| echo 'before opening this. Drift against upstream at refresh time:' | ||
| echo '' | ||
| echo '```text' | ||
| cat "$RUNNER_TEMP/drift.txt" | ||
| echo '```' | ||
| } > "$RUNNER_TEMP/pr-body.md" | ||
| git config user.name 'Apache Maka' | ||
| git config user.email 'commits@maka.apache.org' | ||
| git switch -c "$BRANCH" | ||
| git add scripts/model-metadata/models-dev-api.snapshot.json | ||
| git commit -m "$TITLE" | ||
| # The token travels in a header rather than the remote URL, which git | ||
| # echoes back in its own error messages. | ||
| AUTH="$(printf 'x-access-token:%s' "$GH_TOKEN" | base64 | tr -d '\n')" | ||
| REMOTE="https://github.com/${GITHUB_REPOSITORY}" | ||
| TIP="$(git -c "http.extraheader=Authorization: Basic $AUTH" \ | ||
| ls-remote "$REMOTE" "refs/heads/$BRANCH" | cut -f1)" | ||
| if [ -n "$TIP" ]; then | ||
| # This branch only ever carries commits this job wrote. Anything | ||
| # else is a person working on the open pull request, and a force | ||
| # push would erase it. | ||
| git -c "http.extraheader=Authorization: Basic $AUTH" \ | ||
| fetch --depth=1 "$REMOTE" "refs/heads/$BRANCH" | ||
| if [ "$(git log -1 --format=%s FETCH_HEAD)" != "$TITLE" ]; then | ||
| echo "::error::$BRANCH carries a commit this workflow did not write; refusing to overwrite it." | ||
| exit 1 | ||
| fi | ||
| git -c "http.extraheader=Authorization: Basic $AUTH" push \ | ||
| "--force-with-lease=refs/heads/$BRANCH:$TIP" "$REMOTE" "HEAD:refs/heads/$BRANCH" | ||
| else | ||
| git -c "http.extraheader=Authorization: Basic $AUTH" push \ | ||
| "$REMOTE" "HEAD:refs/heads/$BRANCH" | ||
| fi | ||
| # A plain existence lookup also succeeds for a closed pull request, | ||
| # which would leave a maintainer's decision to close one silently | ||
| # disabling this job forever. Only an open one is one to update. | ||
| if [ "$(gh pr list --head "$BRANCH" --state open --json number --jq 'length')" -gt 0 ]; then | ||
| gh pr edit "$BRANCH" --body-file "$RUNNER_TEMP/pr-body.md" | ||
| echo "Updated the open pull request on $BRANCH." | ||
| else | ||
| gh pr create --draft --base main --head "$BRANCH" \ | ||
| --title "$TITLE" --body-file "$RUNNER_TEMP/pr-body.md" | ||
| fi | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P2] Detect projection changes, not the refresh timestamp\n\n
refresh:model-metadataalways writes a freshorigin.retrievedAt, while this step compares the entire snapshot file. With identical upstream bytes I ran two refreshes:projectionSha256stayed identical but the snapshot bytes changed solely becauseretrievedAtadvanced, so this condition reportschanged=trueand the weekly job commits/opens or force-updates a draft PR even when the build input has not changed. Gate on the semantic projection digest (and, if desired, response hash/ETag changes deliberately) so a no-op weekly refresh remains a no-op.