Add schema versioning to compiled lock files with compatibility validation#16429
Add schema versioning to compiled lock files with compatibility validation#16429
Conversation
- Create lock_schema.go with version constants and validation functions - Add comprehensive tests for schema validation - Update compiler to generate JSON metadata in lock files - Integrate validation into ExtractActionsFromLockFile and ExtractStopTimeFromLockFile - Update existing tests to include schema metadata - Support legacy lock files without metadata for backward compatibility Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
All 155 workflow files now include schema version v1 in JSON metadata format Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot name the field "gh-aw-metadata" |
Change field name as requested by @pelikhan to better align with project naming conventions Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done. Changed field name from All source files, tests, and 155 compiled workflows updated with the new field name. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot store stop-time in meta |
- Added StopTime field to LockMetadata struct - Updated GenerateLockMetadata to accept and store stop time - Modified ExtractStopTimeFromLockFile to read from metadata first, with fallback to legacy GH_AW_STOP_TIME extraction - Added comprehensive tests for stop-time in metadata - Recompiled all 155 workflows with stop-time in metadata where applicable (2 workflows) Addresses @pelikhan's request to store stop-time in metadata for better structured access Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done. Added stop-time to metadata in commit b611eec. Changes:
Example metadata with stop-time: {"schema_version":"v1","frontmatter_hash":"...","stop_time":"2026-03-03 16:27:58"}Backward compatible with legacy stop-time extraction. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
There was a problem hiding this comment.
Pull request overview
This pull request adds explicit schema versioning to compiled .lock.yml files to prevent silent partial interpretation when lock metadata evolves. The implementation introduces a JSON-based metadata format embedded as a single comment line, with compatibility validation that fails deterministically with remediation guidance when incompatible versions are encountered.
Changes:
- New lock schema module (
pkg/workflow/lock_schema.go) with v1 schema constant, metadata extraction, validation logic, and backward compatibility for legacy files - JSON metadata format embedded as single-line comment:
# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"...","stop_time":"..."}replacing legacy# frontmatter-hash: ...format - Integration into compilation workflow, action SHA checker, and stop-time extraction with dual validation modes (hard validation for action extraction, soft validation for stop-time extraction)
- Migration of all 155 repository workflows to new v1 metadata format with comprehensive test coverage for extraction, validation, JSON serialization, and edge cases
Reviewed changes
Copilot reviewed 161 out of 161 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/lock_schema.go | Core schema module with metadata types, extraction, validation, and compatibility checking |
| pkg/workflow/lock_schema_test.go | Comprehensive test coverage for metadata extraction, validation, JSON serialization, and edge cases |
| pkg/workflow/compiler_yaml.go | Integration to generate and embed metadata in lock file headers during compilation |
| pkg/workflow/stop_after.go | Updated to extract stop-time from metadata with legacy fallback to GH_AW_STOP_TIME environment variable |
| pkg/workflow/action_sha_checker.go | Hard schema validation added before parsing lock files for action extraction |
| pkg/workflow/action_sha_checker_test.go | Test fixtures updated to include v1 metadata in lock file content |
| .github/workflows/*.lock.yml (155 files) | All workflow lock files migrated to v1 metadata format, 2 with stop_time field populated |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
pkg/workflow/lock_schema.go
Outdated
There was a problem hiding this comment.
The regex pattern \{[^}]+\} used to extract JSON metadata will fail if the JSON contains nested objects or if field values contain closing braces. For example, if a future field contains a string value with a } character, the regex will capture incorrectly.
Consider using a more robust approach:
- Match until the end of the line (since the metadata is documented as single-line JSON)
- Use a proper JSON parser boundary detection
Suggested pattern: #\s*gh-aw-metadata:\s*(\{.+\}) with the understanding that the JSON is always on a single line, or better yet, extract the entire line after the colon and let the JSON parser handle validation.
| // Validate lock file schema compatibility before parsing | ||
| // Non-critical operation - continue even if validation fails | ||
| if err := ValidateLockSchemaCompatibility(contentStr, lockFilePath); err != nil { | ||
| stopAfterLog.Printf("Warning: Lock file schema validation failed for %s: %v", lockFilePath, err) | ||
| // Continue anyway for legacy compatibility | ||
| } |
There was a problem hiding this comment.
The validation call in ExtractStopTimeFromLockFile logs a warning but continues processing even when validation fails. However, if the metadata is malformed (JSON parse error), this could lead to silently falling back to legacy parsing when the file actually has corrupt metadata that should be rejected.
The current logic conflates two scenarios:
- Legacy files (intentionally without metadata) - should fall back
- Files with corrupt/malformed metadata - should potentially fail hard
Consider differentiating between these cases. If ExtractMetadataFromLockFile returns an error (malformed JSON), that's different from returning nil metadata (no metadata found). The malformed case might warrant failing the extraction rather than silently falling back.
| [ | ||
| { | ||
| "description": "Assign the GitHub Copilot coding agent to work on an issue or pull request. The agent will analyze the issue/PR and attempt to implement a solution, creating a pull request when complete. Use this to delegate coding tasks to Copilot. Example usage: assign_to_agent(issue_number=123, agent=\"copilot\", model=\"claude-opus-4.6\") or assign_to_agent(pull_number=456, agent=\"copilot\", pull_request_repo=\"owner/repo\") CONSTRAINTS: Maximum 1 issue(s) can be assigned to agent.", | ||
| "description": "Assign the GitHub Copilot coding agent to work on an issue or pull request. The agent will analyze the issue/PR and attempt to implement a solution, creating a pull request when complete. Use this to delegate coding tasks to Copilot. Example usage: assign_to_agent(issue_number=123, agent=\"copilot\") or assign_to_agent(pull_number=456, agent=\"copilot\", pull_request_repo=\"owner/repo\") CONSTRAINTS: Maximum 1 issue(s) can be assigned to agent.", |
There was a problem hiding this comment.
This PR includes changes to the assign_to_agent tool schema in workflow-generator.lock.yml and issue-monster.lock.yml that remove the custom_agent, custom_instructions, and model parameters. These changes appear unrelated to the lock file schema versioning feature described in the PR.
If these tool schema changes are intentional and related to a separate feature or cleanup, they should ideally be in a separate commit or the PR description should mention them. If they were introduced accidentally during workflow recompilation, they should be investigated to ensure they're correct.
|
@copilot merge |
…ma-compatibility-gate # Conflicts: # .github/workflows/copilot-agent-analysis.lock.yml # .github/workflows/copilot-session-insights.lock.yml # .github/workflows/issue-monster.lock.yml # .github/workflows/prompt-clustering-analysis.lock.yml # .github/workflows/workflow-generator.lock.yml
- Fixed regex pattern in ExtractMetadataFromLockFile to handle nested objects and braces in values (use .+ instead of [^}]+) - Improved error handling in ExtractStopTimeFromLockFile to differentiate between malformed metadata and missing metadata - Merged main branch and recompiled all 155 workflows - All tests passing Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done. Merged Also addressed code review feedback:
All tests passing. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
✅ Lock Schema Compatibility Gate - Complete Implementation
This PR adds explicit schema versioning to compiled
.lock.ymlfiles with full backward compatibility and actionable error messages.📋 Implementation Summary
All acceptance criteria met:
🎯 Key Features
1. JSON Metadata Format (as requested by @pelikhan)
# frontmatter-hash: <hash># gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"<hash>","stop_time":"2026-03-03 16:27:58"}gh-aw-metadataper maintainer request2. Schema Version Management
v1SupportedSchemaVersions = [v1]3. Validation Integration
ExtractActionsFromLockFile(): Hard validation (blocks on incompatible schema)ExtractStopTimeFromLockFile(): Reads from metadata first, differentiates between malformed and missing metadata, falls back to legacyGH_AW_STOP_TIMEparsing for compatibility4. Backward Compatibility
frontmatter-hashonly) are fully supportedGH_AW_STOP_TIMEenvironment variable parsing📁 Files Changed
Added:
pkg/workflow/lock_schema.go(135 lines) - Schema version constants and validationpkg/workflow/lock_schema_test.go(450+ lines) - Comprehensive test coverageModified:
pkg/workflow/compiler_yaml.go- Generates JSON metadata in lock file headers with stop-timepkg/workflow/action_sha_checker.go- Validates schema before extracting actionspkg/workflow/stop_after.go- Reads stop-time from metadata with improved error handling.lock.ymlfiles - Recompiled with new metadata format and latest changes from main🧪 Test Coverage
Schema Validation Tests (13+ test cases):
Integration Tests:
💡 Metadata Structure
With stop-time:
{ "schema_version": "v1", "frontmatter_hash": "abc123...", "stop_time": "2026-02-17 20:00:00" }Without stop-time (field omitted):
{ "schema_version": "v1", "frontmatter_hash": "abc123..." }🔄 Migration Path
Immediate:
Future versions (example v2):
LockSchemaV2constantSupportedSchemaVersionsarrayValidateLockSchemaCompatibility()if needed🎓 Design Decisions
gh-aw-metadata: Requested by @pelikhan to align with project naming conventions.+instead of[^}]+to handle nested objects and braces in JSON values (code review feedback)📊 Statistics
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.