The Swift Evolution Dashboard is driven by a JSON file of proposal metadata available at https://download.swift.org/swift-evolution/proposals.json
.
In addition, a few other projects in the Swift community are clients of this file.
The current schema has been in place for a number of years now without change. It is missing recent fields like upcoming feature flags, includes outdated fields, and lacks top-level information such as the extraction date and repository SHA the metadata is based on.
This proposal describes intended changes to the metadata schema as well as a transition plan to minimize disruption for clients.
Your feedback on the changes and transition plan are welcome.
All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to me by forum message.
Thank you!
Transition Plan
Review Period
There will be a one month review period on the proposed changes to give community members an opportunity to review and provide feedback.
All known client projects of the existing file will be contacted via GitHub issues.
The review period begins today, March 19, 2024 and runs until April, 19, 2024.
Transition Period
After feedback from the review period is incorporated, there will be a 90-day transition period where the existing and new file schemas will be generated.
-
The existing file will continue to be available at:
https://download.swift.org/swift-evolution/proposals.json
-
The new file will be available at:
https://download.swift.org/swift-evolution/v1/evolution.json
-
During the transition period, the existing
proposals.json
file will include added fields but will not remove or change the structure of any existing fields, so as to not break existing clients. -
The schema version will have a major version of '0' beginning with '0.1.0'
Transition Completion
At the end of the transition period, the existing metadata file no longer be updated.
-
The
proposals.json
file will be replaced with a permanent file that includes a message and the URL of the new metadata file. -
Fields that will no longer be part of the schema will be removed.
-
The schema version will reach 1.0.
Proposed Change Overview
1. Top-level JSON Object
The current JSON file proposals.json
contains an array of proposal objects at its root.
The biggest structural change would be to make the root a JSON object with a proposals
key containing the proposals array.
This allows adding top-level fields such as the extraction date and SHA of the repository commit the metadata is based on.
2. New file name
Name the new file evolution.json
to signify the difference from proposals.json
.
The new name helps indicate that the file contains metadata beyond just the proposals. It also makes it easy to differentiate between the legacy format and the new format.
3. Individual field changes
There are a number of individual field changes described in the section Detailed Individual Field Changes below.
Detailed Individual Field Changes
Top-Level Field Additions
All top-level fields are new to the schema.
Proposal Metadata
proposals
: An array of proposal metadata objects that is currently the root of theproposals.json
file.
Extraction Details
-
creationDate
: An ISO 8601 date string of when the metadata was generated. -
commit
: Theswift-evolution
repository commit hash used to generate the metadata. -
toolVersion
: The version of the extraction tool that created the file. -
schemaVersion
: The version of the schema used in the file.
Aggregate Values
-
implementationVersions
: An array of strings containing a uniqued list of versions found in proposals with āImplementedā status, sorted from lowest to highest version.This list will be used by the SE Dashboard to populate the version filters in the user interface. It will ensure the interface is always up to date with the repository, instead of requiring manually checking for proposal changes and updating the script to add new versions.
SE Proposal Metadata Changes
Support multiple release managers
Some evolution proposals have multiple release managers. Currently only the first is included in the metadata.
-
Add
releaseManagers
as an array of release managers. -
Remove
releaseManager
field.
Both keys would be generated during the transition period.
Add support for upcoming feature flags
- Add an
upcomingFeatureFlag
field.
Since most proposals do not have an upcoming feature flag, this will be an optional field.
This field consists of a JSON object with two fields:
-
flag
: The flag itself -
enabledInLanguageMode
: Language mode version when feature is always enabled. Field is omitted when there is no announced language mode. -
available
: Optional field containing the language release version (e.g. "5.10") when the flag is available, if not the same as the release in which the feature is implemented.
For example:
"upcomingFeatureFlag" : {
"flag" : "BareSlashRegexLiterals",
"enabledInLanguageMode" : "6"
}
Changes to errors and warnings
-
Add a
code
fieldThe code is a unique integer across warnings and errors (i.e. issues). This allows clients to process issues based on a stable value rather than depending on exact wording in the message.
-
Add a
recoverySuggestion
field.The reported errors and warnings are almost always because of unexpected or malformed Markdown in the proposal.
Currently some warnings and errors try to cram what might be wrong in the
messages
field. Adding the field gives a clear distinction between what the problem is and what needs to be done to fix the problem. It also allows for a longer suggestion.Recovery suggestions are intended to provide enough information to address the problem and, when practical, to help prevent follow-on problems.
For example:
message: āProposal has no authorsā
recoverySuggestion: āAuthors should be listed in a header field:
* Authors: [PersonName](https://github.com/profileLink).
- For multiple authors, use a comma separated list.
- If an author has no GitHub profile, list the name as plain text.
- Note that only GitHub profile links will be extracted into metadata." -
Remove
stage
field.This field can contain one of two values: āparseā or āvalidateā.
The distinction seems to be whether there is a formatting error that causes information to be unable to be found (parse) or a logical error in the parsed information (validate).
In practice the value of this field doesnāt provide a useful distinction.
Remove leading dot from status values
-
Replace status value strings like
".accepted"
with dot-less strings like"accepted"
The dot seems to originally been intended to be the same value as in the corresponding case statement in a switch statement. Including the dot does not seem to serve any useful purpose.
Add a diagnostic string for the error state of status
-
Add
reason
key to status object when status state is 'error'This is useful both in encoding, where issues in extracting the status from the proposal Markdown can have a succinct reason for the failure, and in decoding where, for example, a Swift enum modeling status can decode an unknown new state value as an error with the unknown status noted in the reason string.
Remove unused fields from TrackingBug
-
Remove
assignee
,radar
,resolution
,status
,title
, andupdated
fieldsOne intent of the legacy format was to provide metadata about the status of all tracking bugs.
The primary fields
id
andlink
are parsed from the proposal itself.The secondary fields
assignee
,radar
,resolution
,status
,title
, andupdated
were all populated by a second pass of fetching from JIRA.This functionality was not updated when the Swift project moved from JIRA to GitHub Issues in spring 2022. For the past two years, all fields except for
id
andlink
have been empty.The SE Dashboard does not use the additional fields and they have no known clients. There do not seem to be any requests in the past two years from the community asking for these fields to be populated.
This change would keep the primary
id
andlink
fields that are currently extracted from the source proposal files and remove the secondary fields.Since the id and link for each issue will remain, any client of the metadata file can use the GitHub API to get additional details as desired.
Add support for proposal review discussions
- Add a
discussions
field.
In the proposal file, the header field is 'Review' but is defined as the discussion about the proposal. For clarity in the metadata, the field name will be discussions
.
This field is an array of JSON objects with two fields:
-
name
: The name of the discussion "pitch" "review" "acceptance" -
link
: The link to the discussion.
For example:
"discussions" : [
{
"name" : "pitch",
"link" : "https://forums.swift.org/t/pitch-usability-of-global-actor-isolated-types/70799"
},
{
"name" : "review",
"link" : "https://forums.swift.org/t/se-0434-usability-of-global-actor-isolated-types/71187"
},
]
Discussions about this addition:
original proposal post
additional commentary
Add support for previous proposal IDs
- Add a
previousProposalIDs
field.
A proposal can have an optional list of proposals that form a 'line of succession'. For example, part of a previous proposal may be extracted and pitched as a separate proposal. The criteria is described in more detail in the Swift Evolution proposal template.
This field is an optional array of proposal ID strings extracted from the 'Previous Proposal' header field.
Discussions about this addition:
original proposal post
additional commentary
Schema Summary
Top level object:
{
"creationDate": String, // (ISO-8601 date format)
"commit": String,
"implementedVersions": [String],
"proposals": [Proposal],
"schemaVersion": String,
"toolVersion": String
}
Proposal object:
{
"id": String, // SE-NNNN, e.g. "SE-0147"
"title": String,
"summary": String,
"link": String,
"sha": String, // SHA of the proposal's Markdown file's latest update
"authors": [ // [Proposal.Person]
{
"name": String,
"link": String // warns on absence
}
],
"reviewManagers": [ // [Proposal.Person]
{
"name": String,
"link": String // warns on absence
}
],
"status": { // Proposal.Status
"state": String, // Status state name, e.g. "implemented"
"start": String?, // ISO 8601 date string, key only present for status states with dates
"end": String?, // ISO 8601 date string, same as above
"version": String?, // swift version, e.g. "3.0.2", present only for 'implemented' state
"reason": String? // reason for error state, present only for 'error' state
}
},
"discussions": [ // [Proposal.Discussion] A list of the related proposal discussions
{
"name": String, // "Pitch", "Review", "Acceptance", ...
"link": String
}
],
"trackingBugs": [ // [Proposal.TrackingBug]?
{
"id": String,
"link": String,
}
],
"implementation": [ // [Proposal.Implementation]?
{
"type": String, // "commit" | "pull"
"account": String,
"repository": String,
"id": String
}
],
"previousProposalIDs": [String]?, // IDs of proposals that form a line of succession to this proposal
"upcomingFeatureFlag" : { // [Proposal.UpcomingFeatureFlag]?
"flag" : String
"enabledInLanguageMode" : String?, // Language mode version when feature is always enabled. Omitted when there is no announced language mode
"available" : String?, // Optional field containing the language release version when the flag is available, if not the same as the release in which the feature is implemented.
},
"warnings": [ // [Proposal.Issue]?, key omitted if no values
{
"code": Int, // unique identifier across warnings and errors
"kind": "warning", // differentiates this from an error
"message": String, // human-readable description of what's wrong
"recoverySuggestion": String // human-readable description of how to address the issue
}
],
"errors": [ // [Proposal.Issue]?, key omitted if no values
{
"code": Int, // unique identifier across warnings and errors
"kind": "error", // differentiates this from an error
"message": String, // human-readable description of what's wrong
"recoverySuggestion": String // human-readable description of how to address the issue
}
]
}
Revisions:
3/20/24
- Changed top-level field names
- From
sha
tocommit
- From
extractionDate
tocreationDate
- From
3/23/24
- Removed section on using default
Codable
structure forstatus
object - Added an optional
reason
field for error status - Changed
untilLanguageMode
toenabledInLanguageMode
to match the LSG's preferred naming.
4/1/24
- Fix typo in domain name of
download.swift.org
.
4/4/24
- Updated proposed fields for
upcomingFeatureFlag
- Add optional
available
field for flags that are available after proposal implementation version - Make
enabledInLanguageMode
field optional
- Add optional
4/12/24
- Add proposed field for
discussions
- Add proposed field for
previousProposalIDs