chore(deps): bump github.com/qmuntal/gltf from 0.28.0 to 0.29.0 in the minor group #83
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| # Manual trigger. Release is gated on a SUCCESSFUL CI run on main | |
| # (release.yml keys off workflow_run), so a push event GitHub drops during | |
| # an Actions incident leaves main permanently unreleased. Re-running an | |
| # OLDER run is not a substitute: workflow_run hands release.yml that run's | |
| # head SHA, so it would publish from a stale tree. This lets a maintainer | |
| # run CI against main's current tip and let the release chain proceed. | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| # Least privilege for the whole workflow. The repository default is read/WRITE, | |
| # which every job here would otherwise inherit for no reason — CI only reads the | |
| # tree. A job that genuinely needs more asks for it explicitly (see release.yml, | |
| # which scopes contents: write to the one job that publishes). | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| shell: bash | |
| jobs: | |
| # A CHANGELOG or docs-only PR cannot break the Go build, but it used to spend | |
| # four runners proving it. This job decides once, and the Go jobs below gate | |
| # on it. | |
| # | |
| # Why a job and not `paths-ignore:` on the workflow itself: Lint, Test, | |
| # Vulnerability Scan and Conventional Commits Check are REQUIRED checks on | |
| # main (ruleset 20694555). A workflow that never starts never reports them, | |
| # and the PR sits un-mergeable forever. A job skipped by `if:` DOES report — | |
| # GitHub counts a skipped required check as passing — so the filter has to | |
| # live inside a workflow that always runs. | |
| # | |
| # CodeQL is deliberately left alone: its required "CodeQL" context comes from | |
| # the github-advanced-security app when results are uploaded, not from a job | |
| # name, so nothing we can skip would still report it. | |
| changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| permissions: | |
| # Reading the PR's file list goes through the pulls API, which the | |
| # workflow-wide contents: read alone does not cover on a fork PR. | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| steps: | |
| - name: Classify the changed files | |
| id: filter | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REPO: ${{ github.repository }} | |
| EVENT: ${{ github.event_name }} | |
| PR: ${{ github.event.number }} | |
| BEFORE: ${{ github.event.before }} | |
| AFTER: ${{ github.sha }} | |
| run: | | |
| set -euo pipefail | |
| if [ "$EVENT" = "pull_request" ]; then | |
| files=$(gh api "repos/$REPO/pulls/$PR/files" --paginate --jq '.[].filename') | |
| elif [ -n "${BEFORE:-}" ] && [ "$BEFORE" != "0000000000000000000000000000000000000000" ]; then | |
| files=$(gh api "repos/$REPO/compare/$BEFORE...$AFTER" --jq '.files[].filename') | |
| else | |
| files='' | |
| fi | |
| # An empty list means we could not tell what changed (force push, new | |
| # branch, truncated compare). Run everything — the filter is an | |
| # optimisation and must never be the reason a break slips through. | |
| if [ -z "$files" ] || grep -qvE '(\.md$|^docs/|^mkdocs\.yml$|^requirements-docs\.txt$)' <<< "$files"; then | |
| echo "code=true" >> "$GITHUB_OUTPUT" | |
| echo "Code changed — running the full suite." | |
| else | |
| echo "code=false" >> "$GITHUB_OUTPUT" | |
| echo "Docs-only change — skipping the Go jobs." | |
| fi | |
| echo "$files" | sed 's/^/ /' | |
| conventional-commits: | |
| name: Conventional Commits Check | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Conventional Commits | |
| uses: webiny/action-conventional-commits@7f91b1595ca1951cdb671ddc9f07a49081ec5b69 # v1.4.2 | |
| with: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| allowed-commit-types: "feat,fix,cicd,chore,patch,release,test,docs,refactor,ci,dev" | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| needs: [conventional-commits, changes] | |
| if: needs.changes.outputs.code == 'true' | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: golangci-lint | |
| uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0 | |
| with: | |
| version: v2.12.2 | |
| args: --timeout=5m | |
| skip-cache: true | |
| skip-save-cache: true | |
| env: | |
| GOPROXY: https://proxy.golang.org,direct | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| needs: [lint, changes] | |
| if: needs.changes.outputs.code == 'true' | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Run tests | |
| # goifc is pure Go with no cgo dependencies. Pinning CGO_ENABLED=0 | |
| # asserts that property in CI: if a dependency ever sneaks in a cgo | |
| # requirement, the build fails loudly here instead of silently | |
| # linking against system libraries. | |
| # | |
| # -coverpkg=./... attributes coverage to the package that OWNS the line | |
| # rather than the package whose test executed it, which is the only way | |
| # the cross-package paths (step parsed by a model test, geometry driven | |
| # from Assemble) count at all. It reports one module-wide number instead | |
| # of four per-package ones — 85.3% at the time of writing. | |
| env: | |
| CGO_ENABLED: '0' | |
| run: go test -v -covermode=atomic -coverpkg=./... -coverprofile=coverage.out ./... | |
| # Coverage reporting must never be able to fail a REQUIRED check on | |
| # somebody else's outage, so fail_ci_if_error stays false. The token is | |
| # optional here: blox-eng/goifc is public, so tokenless upload from | |
| # Actions works, and the secret is read for the day that stops being true. | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 | |
| with: | |
| files: coverage.out | |
| fail_ci_if_error: false | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| govulncheck: | |
| name: Vulnerability Scan | |
| runs-on: ubuntu-latest | |
| needs: [conventional-commits, changes] | |
| if: needs.changes.outputs.code == 'true' | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| # govulncheck is the complement to Dependabot, not a duplicate: Dependabot | |
| # tells you a newer version exists, govulncheck tells you whether a known | |
| # vulnerability is actually REACHABLE from this code — and it covers the | |
| # Go standard library, which a dependency bump never touches. The pinned | |
| # toolchain is exactly the kind of thing this catches — and did, on the first | |
| # run: GO-2026-4601 (net/url IPv6 parsing) was reachable from WriteGLB via | |
| # gltf.Encoder.Encode on the then-pinned 1.25.4, fixed in 1.25.8. | |
| - uses: golang/govulncheck-action@032d45514ae346b1db93c04b0c90b841c370344f # v1.1.0 | |
| with: | |
| # go-version-input defaults to 'stable', and the action forwards BOTH | |
| # it and go-version-file to setup-go, which then ignores the file and | |
| # warns. That silently scanned whatever 'stable' happened to be rather | |
| # than the toolchain we ship — the exact opposite of the paragraph | |
| # above. Blanking it makes go.mod authoritative for real. | |
| go-version-input: '' | |
| go-version-file: go.mod | |
| go-package: ./... | |
| fuzz: | |
| name: Fuzz Smoke | |
| runs-on: ubuntu-latest | |
| needs: [conventional-commits, changes] | |
| if: needs.changes.outputs.code == 'true' | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| # What this job does and does NOT buy, stated honestly: replaying the | |
| # seed corpus and any committed testdata/fuzz/ crashers already happens | |
| # under plain `go test ./...` in the Test job above, which is a REQUIRED | |
| # check. So regression-catching is banked there, not here. All this job | |
| # adds is 60s of coverage-guided exploration per target — thin against a | |
| # strict STEP grammar, but cheap, and it is where a new crasher would | |
| # first show up. Real assurance needs a long scheduled run, not this. | |
| # That run now exists: .github/workflows/fuzz-nightly.yml (30m/target, | |
| # nightly). | |
| # Deliberately not a required check: a fuzz OOM or timeout is infra | |
| # noise and must not block a merge. fuzz-smoke.sh enforces that split — | |
| # it forgives the known -fuzztime shutdown race and nothing else, so a | |
| # crasher still fails the job loudly. | |
| - name: Fuzz the STEP parser | |
| env: | |
| CGO_ENABLED: '0' | |
| run: .github/scripts/fuzz-smoke.sh ./step/ FuzzParseBytes 60s | |
| - name: Fuzz the full assemble path | |
| env: | |
| CGO_ENABLED: '0' | |
| run: .github/scripts/fuzz-smoke.sh . FuzzAssemble 60s | |
| - name: Upload crashers | |
| if: failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: fuzz-crashers | |
| path: '**/testdata/fuzz/**' | |
| if-no-files-found: ignore |