Skip to content

Conversation

@SamMorrowDrums
Copy link
Collaborator

@SamMorrowDrums SamMorrowDrums commented Dec 12, 2025

Summary

Improves license file automation to proactively fix license files on PRs, eliminating the common "license check failed, please run script/licenses" workflow friction.

Changes

1. Auto-Commit Workflow

The license-check.yml workflow now:

  • Tries to auto-commit: Directly pushes license fixes to the PR branch
  • Falls back to instructions: If push fails (e.g., fork without maintainer permissions), comments once with clear instructions
  • Prevents spam: Checks for existing comments before posting
  • Always fails check: If licenses need updating, the check fails regardless (blocking merge until fixed)

2. Deterministic License Generation

  • Uses LC_ALL=C sort throughout script/licenses for locale-independent sorting
  • Ensures consistent output across different systems and CI environments

3. CI Reproducibility

  • Pins go-licenses version in CI via CI=true environment variable
  • Generates architecture-specific license files (darwin, linux, windows)

Behavior

Internal PRs (or with maintainer permissions)

  1. PR created/updated with dependency changes
  2. Workflow detects license files are out of date
  3. Workflow pushes fix automatically
  4. Check passes on next run
  5. PR ready to merge

Fork PRs (without maintainer permissions)

  1. PR created/updated with dependency changes
  2. Workflow detects license files are out of date
  3. Workflow comments once with instructions 💬
  4. Check fails until contributor fixes manually
  5. No duplicate comments on subsequent pushes

All Cases

  • Check always fails if licenses need updating (blocks merge)
  • Comments only once per PR (no spam)
  • Clear instructions for manual fix when needed

Technical Details

  • Single job workflow: No child PR management, much simpler
  • Graceful degradation: Works for all PR types (internal, fork, dependabot)
  • Idempotent: Multiple runs don't create duplicate comments
  • Fast feedback: Fixes applied immediately when possible

Testing

Tested with:

  • Internal PRs: Auto-commit works
  • Fork PRs: Comment posted, no spam on subsequent runs
  • Locale consistency: LC_ALL=C ensures deterministic sorting

Resolves

Fixes the manual "run script/licenses" workflow friction while keeping simple, predictable behavior.

The licenses script now:
- Generates separate license reports per GOOS/GOARCH combination
- Groups identical reports together (comma-separated arch names)
- Adds a Table of Contents at the top of each platform file
- Handles cases where different architectures have different dependencies
  (e.g., x/sys/unix vs x/sys/windows, mousetrap on Windows only)

This addresses the issue discovered in cli/cli where some deps changed
which changed the mod graph for different GOARCH and affected the
exported licenses because go-licenses tries to find common ancestors.
Copilot AI review requested due to automatic review settings December 12, 2025 11:02
@SamMorrowDrums SamMorrowDrums requested a review from a team as a code owner December 12, 2025 11:02
@github-actions
Copy link

📜 License files updated

I noticed the third-party license files were out of date and pushed a fix to this PR.

What changed: Dependencies were added, removed, or updated, which requires regenerating the license documentation.

What I did: Ran ./script/licenses and committed the result.

Please pull the latest changes before pushing again.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the license automation workflow by automatically regenerating and committing license files when dependency changes are detected in pull requests, eliminating manual intervention. It also pins the go-licenses tool version for CI reproducibility and excludes third-party dependencies from CodeQL scanning.

Key changes:

  • Transforms license-check workflow from fail-only to auto-fix with PR comments
  • Pins go-licenses to v2.0.1 (commit hash) in CI environments while keeping @latest for local development
  • Excludes third-party directory and license markdown files from CodeQL analysis

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

File Description
.github/workflows/license-check.yml Complete workflow rewrite: now regenerates license files, commits fixes to PR branch, and posts explanatory comment instead of just failing
script/licenses Adds conditional go-licenses version pinning based on CI environment variable
script/licenses-check Adds conditional go-licenses version pinning and improves error messages with platform-specific context
.github/workflows/code-scanning.yml Adds paths-ignore configuration to exclude third-party directory and license files from CodeQL scanning

Address review feedback:
- Remove bash 4.0+ associative array requirement for macOS compatibility
- Add cross-platform hash function (md5sum on Linux, md5 on macOS)
- Ensure deterministic iteration order using sorted groups file
- Add better error handling for failed go-licenses commands
- Fix grammar: 'architecture(s)' -> 'architectures'
- Add documentation for third-party/ being a union of all architectures
- Use file-based state instead of associative arrays for portability
@SamMorrowDrums SamMorrowDrums force-pushed the improve/license-automation branch from e382970 to a27f96f Compare December 12, 2025 11:09
@github-actions
Copy link

📜 License files updated

I noticed the third-party license files were out of date and pushed a fix to this PR.

What changed: Dependencies were added, removed, or updated, which requires regenerating the license documentation.

What I did: Ran ./script/licenses and committed the result.

Please pull the latest changes before pushing again.

@SamMorrowDrums SamMorrowDrums force-pushed the improve/license-automation branch 4 times, most recently from 29a3e49 to c5c0934 Compare December 12, 2025 11:33
@SamMorrowDrums SamMorrowDrums force-pushed the fix/arch-specific-licenses branch from bdc44fa to ee28e6d Compare December 12, 2025 11:36
@SamMorrowDrums SamMorrowDrums force-pushed the improve/license-automation branch from c5c0934 to be0560b Compare December 12, 2025 11:37
@SamMorrowDrums SamMorrowDrums force-pushed the fix/arch-specific-licenses branch from ee28e6d to 8855c2c Compare December 12, 2025 11:43
- Check now regenerates using ./script/licenses and compares
- Add GOROOT/PATH setup in CI to fix go-licenses module info errors
- Check both license files AND third-party directory for changes
- See: google/go-licenses#244
@SamMorrowDrums SamMorrowDrums force-pushed the fix/arch-specific-licenses branch from 8855c2c to eb7d73c Compare December 12, 2025 12:23
@SamMorrowDrums SamMorrowDrums force-pushed the improve/license-automation branch from be0560b to fca825e Compare December 12, 2025 12:26
The sort command uses locale-specific ordering which can differ between
systems. Use LC_ALL=C to ensure consistent ordering in CI and locally.
Changes:
- Pin go-licenses version in CI for reproducibility (commit 5348b744)
- Add GOROOT/PATH setup for 'Package does not have module info' fix
- Update license-check.yml to auto-fix and push to PR branches
- Add CI=true env var to use pinned go-licenses version
- Add dependabot exclusion from auto-fix workflow
- Add code-scanning exclusion for third-party files
@SamMorrowDrums SamMorrowDrums force-pushed the improve/license-automation branch from fca825e to 58f49f5 Compare December 12, 2025 13:49
After the bot pushes license fixes, check if the PR now only contains
license file changes. If so, close it automatically with a comment
explaining that the license updates are complete.

This prevents stale PRs from accumulating when someone creates a PR
just to fix licenses, or when all other changes were already merged
to the base branch.
Creates stacked PRs to fix license issues:
- Detects when a PR needs license updates
- Creates child PR: main <- PR:feature <- PR:license-fix
- Tracks PRs with metadata and hash of license changes
- Auto-closes if user fixes licenses manually
- Auto-closes and recreates if dependencies change
- Prevents multiple fix PRs for same base PR

Rules:
- Only targets PRs against main (not stacked PRs)
- Only runs on ready-for-review PRs (not drafts)
- Skips bots and forks
- Hash-based detection avoids unnecessary work
Dependabot PRs frequently need license updates and can't be merged until
fixed. The auto-fix workflow helps by creating a child PR with the
license changes, making it easy to merge both together.
- Remove dependabot exclusion (we want to support dependabot PRs)
- Comment indentation already fixed
- CI env var already set for reproducibility
Moved the 'targets main' check from job if: to workflow on.pull_request.branches.
This prevents the workflow from even triggering for PRs targeting other branches,
saving CI resources.

Draft check is implicit in the types list (opened + ready_for_review).
Fork check must stay in if: condition (can't be filtered in on: block).
Combines both workflows into one with two jobs:
1. license-check: Checks licenses, fails if needed, sets outputs
2. auto-create-fix-pr: Creates child PR if needed (only for non-forks)

Benefits:
- Single workflow file, easier to maintain
- Check fails (blocks merge) while still creating helpful fix PR
- Fork detection in first job, second job skips for forks
- Hash-based tracking prevents duplicate PRs
Much simpler workflow:
1. Always try to auto-commit fix directly to PR branch
2. If push fails (fork without permissions), comment once with instructions
3. Don't create child PRs - just fix in place or give instructions
4. Only comment if not already commented (prevent spam)
5. Always fail check if licenses need updating

Benefits:
- Much simpler - single job
- No child PR management complexity
- Clear UX: either fixed or instructed
- Works for all PRs (internal/fork/dependabot)
Base automatically changed from fix/arch-specific-licenses to main December 12, 2025 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants