Model Export: SavedModel, TFLite, and ONNX Support #1055
Workflow file for this run
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
| name: Lint | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| issue_comment: | |
| types: [created] | |
| concurrency: | |
| group: >- | |
| lint-${{ | |
| github.event_name == 'issue_comment' | |
| && format('pr-{0}', github.event.issue.number) | |
| || github.ref | |
| }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| frontend-lint: | |
| name: Frontend Lint | |
| if: >- | |
| github.event_name != 'issue_comment' | |
| || ( | |
| github.event.issue.pull_request | |
| && contains(github.event.comment.body, '/lint') | |
| && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) | |
| ) | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: tensormap-frontend | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event_name == 'issue_comment' && format('refs/pull/{0}/head', github.event.issue.number) || '' }} | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| cache-dependency-path: tensormap-frontend/package-lock.json | |
| - run: npm ci | |
| - name: ESLint | |
| id: eslint | |
| continue-on-error: true | |
| run: npx eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0 | |
| - name: Prettier | |
| id: prettier | |
| continue-on-error: true | |
| run: npx prettier --check "src/**/*.{js,jsx,json,css}" | |
| - name: Comment on PR | |
| if: github.event_name != 'push' && (steps.eslint.outcome == 'failure' || steps.prettier.outcome == 'failure') | |
| continue-on-error: true | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const marker = '<!-- lint-frontend-bot -->'; | |
| let body = marker + '\n## Frontend Lint Failed\n\n'; | |
| if ('${{ steps.eslint.outcome }}' === 'failure') { | |
| body += '**ESLint:** Run `npx eslint --fix . --ext js,jsx` in `tensormap-frontend/`\n\n'; | |
| } | |
| if ('${{ steps.prettier.outcome }}' === 'failure') { | |
| body += '**Prettier:** Run `npx prettier --write "src/**/*.{js,jsx,json,css}"` in `tensormap-frontend/`\n\n'; | |
| } | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existing = comments.find(c => c.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| comment_id: existing.id, body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| issue_number: context.issue.number, body, | |
| }); | |
| } | |
| - name: Delete stale comment | |
| if: github.event_name != 'push' && steps.eslint.outcome == 'success' && steps.prettier.outcome == 'success' | |
| continue-on-error: true | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const marker = '<!-- lint-frontend-bot -->'; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existing = comments.find(c => c.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.deleteComment({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| comment_id: existing.id, | |
| }); | |
| } | |
| - name: Fail if checks failed | |
| if: steps.eslint.outcome == 'failure' || steps.prettier.outcome == 'failure' | |
| run: exit 1 | |
| backend-lint: | |
| name: Backend Lint | |
| if: >- | |
| github.event_name != 'issue_comment' | |
| || ( | |
| github.event.issue.pull_request | |
| && contains(github.event.comment.body, '/lint') | |
| && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) | |
| ) | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: tensormap-backend | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event_name == 'issue_comment' && format('refs/pull/{0}/head', github.event.issue.number) || '' }} | |
| - uses: astral-sh/setup-uv@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: uv sync --frozen --extra dev | |
| - name: Ruff lint | |
| id: ruff-lint | |
| continue-on-error: true | |
| run: uv run ruff check . | |
| - name: Ruff format | |
| id: ruff-format | |
| continue-on-error: true | |
| run: uv run ruff format --check . | |
| - name: Comment on PR | |
| if: github.event_name != 'push' && (steps.ruff-lint.outcome == 'failure' || steps.ruff-format.outcome == 'failure') | |
| continue-on-error: true | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const marker = '<!-- lint-backend-bot -->'; | |
| let body = marker + '\n## Backend Lint Failed\n\n'; | |
| if ('${{ steps.ruff-lint.outcome }}' === 'failure') { | |
| body += '**Ruff lint:** Run `uv run ruff check --fix .` in `tensormap-backend/`\n\n'; | |
| } | |
| if ('${{ steps.ruff-format.outcome }}' === 'failure') { | |
| body += '**Ruff format:** Run `uv run ruff format .` in `tensormap-backend/`\n\n'; | |
| } | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existing = comments.find(c => c.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| comment_id: existing.id, body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| issue_number: context.issue.number, body, | |
| }); | |
| } | |
| - name: Delete stale comment | |
| if: github.event_name != 'push' && steps.ruff-lint.outcome == 'success' && steps.ruff-format.outcome == 'success' | |
| continue-on-error: true | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const marker = '<!-- lint-backend-bot -->'; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existing = comments.find(c => c.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.deleteComment({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| comment_id: existing.id, | |
| }); | |
| } | |
| - name: Fail if checks failed | |
| if: steps.ruff-lint.outcome == 'failure' || steps.ruff-format.outcome == 'failure' | |
| run: exit 1 | |
| rebase-check: | |
| name: Rebase Check | |
| if: >- | |
| github.event_name == 'pull_request' | |
| || ( | |
| github.event_name == 'issue_comment' | |
| && github.event.issue.pull_request | |
| && contains(github.event.comment.body, '/lint') | |
| && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) | |
| ) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event_name == 'issue_comment' && format('refs/pull/{0}/head', github.event.issue.number) || '' }} | |
| - name: Check rebase status | |
| id: rebase | |
| run: | | |
| git fetch origin main | |
| # Check for merge commits in the PR branch | |
| MERGE_COMMITS=$(git log --merges origin/main..HEAD --oneline) | |
| # Check how many commits the branch is behind main | |
| BEHIND_COUNT=$(git rev-list --count HEAD..origin/main) | |
| echo "merge_commits<<EOF" >> "$GITHUB_OUTPUT" | |
| echo "$MERGE_COMMITS" >> "$GITHUB_OUTPUT" | |
| echo "EOF" >> "$GITHUB_OUTPUT" | |
| echo "behind_count=$BEHIND_COUNT" >> "$GITHUB_OUTPUT" | |
| - name: Comment if rebase needed | |
| if: steps.rebase.outputs.behind_count != '0' || steps.rebase.outputs.merge_commits != '' | |
| continue-on-error: true | |
| uses: actions/github-script@v7 | |
| env: | |
| BEHIND_COUNT: ${{ steps.rebase.outputs.behind_count }} | |
| MERGE_COMMITS: ${{ steps.rebase.outputs.merge_commits }} | |
| with: | |
| script: | | |
| const marker = '<!-- rebase-bot -->'; | |
| const behind = parseInt(process.env.BEHIND_COUNT); | |
| const mergeCommits = (process.env.MERGE_COMMITS || '').trim(); | |
| let body = marker + '\n## Rebase Required\n\n'; | |
| if (behind > 0) { | |
| body += `Your branch is **${behind} commit(s) behind \`main\`**. Please rebase onto the latest \`main\`.\n\n`; | |
| } | |
| if (mergeCommits) { | |
| body += '**Merge commits detected** in this PR. Please use rebase instead of merge:\n\n'; | |
| body += '```\n' + mergeCommits + '\n```\n\n'; | |
| } | |
| body += '### How to fix\n```bash\ngit fetch origin\ngit rebase origin/main\ngit push --force-with-lease\n```\n'; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existing = comments.find(c => c.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| comment_id: existing.id, body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| issue_number: context.issue.number, body, | |
| }); | |
| } | |
| - name: Delete stale comment | |
| if: steps.rebase.outputs.behind_count == '0' && steps.rebase.outputs.merge_commits == '' | |
| continue-on-error: true | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const marker = '<!-- rebase-bot -->'; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existing = comments.find(c => c.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.deleteComment({ | |
| owner: context.repo.owner, repo: context.repo.repo, | |
| comment_id: existing.id, | |
| }); | |
| } |