зеркало из https://github.com/github/docs.git
Set up tests, start formatting messages
This commit is contained in:
Родитель
7e07c1c831
Коммит
96e4ea9499
|
@ -1,4 +1,4 @@
|
|||
const { diff } = require('@graphql-inspector/core')
|
||||
const { diff, ChangeType } = require('@graphql-inspector/core')
|
||||
const { loadSchema } = require('@graphql-tools/load')
|
||||
const git = require('../../lib/git-utils')
|
||||
const fs = require('fs')
|
||||
|
@ -8,9 +8,9 @@ if (!process.env.GITHUB_TOKEN) {
|
|||
process.exit(1)
|
||||
}
|
||||
|
||||
main()
|
||||
// main()
|
||||
|
||||
async function main () {
|
||||
async function main() {
|
||||
// Load the previous schema from this repo
|
||||
// TODO -- how to make sure that this script runs _before_ this artifact is updated?
|
||||
// Maybe hook into the existing `update-files` script instead of being a stand-alone script.
|
||||
|
@ -20,26 +20,59 @@ async function main () {
|
|||
const tree = await git.getTree('github', 'github', 'heads/master')
|
||||
const schemaFileBlob = tree.find(entry => entry.path.includes('config/schema.docs.graphql') && entry.type === 'blob')
|
||||
const newSchemaBuffer = await git.getContentsForBlob('github', 'github', schemaFileBlob)
|
||||
const changelogEntry = createChangelogEntry(oldSchemaString, newSchemaBuffer.toString())
|
||||
if (changelogEntry) {
|
||||
const previousChangelogString = fs.readFileSync('lib/graphql/static/changelog.json')
|
||||
const previousChangelog = JSON.parse(previousChangelogString)
|
||||
// add a new entry to the changelog data
|
||||
previousChangelog.unshift(changelogEntry)
|
||||
// rewrite the updated changelog
|
||||
fs.writeFileSync('lib/graphql/static/changelog.json', JSON.stringify(previousChangelog, null, 2))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Compare `oldSchemaString` to `newSchemaString`, and if there are any
|
||||
// changes that warrant a changelog entry, return a changelog entry.
|
||||
// Otherwise, return null.
|
||||
async function createChangelogEntry(oldSchemaString, newSchemaString) {
|
||||
// Create schema objects out of the strings
|
||||
const oldSchema = await loadSchema(oldSchemaString)
|
||||
const newSchema = await loadSchema(newSchemaBuffer.toString())
|
||||
const newSchema = await loadSchema(newSchemaString)
|
||||
|
||||
// Generate changes between the two schemas
|
||||
const changes = diff(oldSchema, newSchema)
|
||||
console.log(changes)
|
||||
const changesToReport = []
|
||||
changes.forEach(function (change) {
|
||||
if (CHANGES_TO_REPORT.includes(change.type)) {
|
||||
changesToReport.push(change)
|
||||
} else if (CHANGES_TO_IGNORE.includes(change.type)) {
|
||||
// Do nothing
|
||||
} else {
|
||||
throw "This change type should be added to CHANGES_TO_REPORT or CHANGES_TO_IGNORE: " + change.type
|
||||
}
|
||||
})
|
||||
|
||||
const { schemaChangesToReport, previewChangesToReport } = segmentPreviewChanges(changesToReport)
|
||||
// If there were any changes, create a changelog entry
|
||||
if (changes.length > 0) {
|
||||
const previousChangelogString = fs.readFileSync('lib/graphql/static/changelog.json')
|
||||
const previousChangelog = JSON.parse(previousChangelogString)
|
||||
|
||||
if (schemaChangesToReport.length > 0 || previewChangesToReport.length > 0) {
|
||||
// Build a `yyyy-mm-dd`-formatted date string
|
||||
const today = new Date()
|
||||
const todayString = String(today.getFullYear()) + '-' + String(today.getMonth() + 1).padStart(2, '0') + '-' + String(today.getDate()).padStart(2, '0')
|
||||
|
||||
// TODO format `changes` into strings
|
||||
const formattedChanges = []
|
||||
const changelogEntry = {
|
||||
date: todayString,
|
||||
schemaChanges: [],
|
||||
previewChanges: [],
|
||||
upcomingChanges: [],
|
||||
}
|
||||
|
||||
const schemaChange = {
|
||||
title: 'The GraphQL schema includes these changes:',
|
||||
// Replace single quotes which wrap field/argument/type names with backticks
|
||||
changes: changesToReport.map(function (change) { return change.message.replace(/'([a-zA-Z\. :!]+)'/g, '`$1`') })
|
||||
}
|
||||
changelogEntry.schemaChanges.push(schemaChange)
|
||||
|
||||
// TODO how are these populated?
|
||||
// {
|
||||
|
@ -62,23 +95,78 @@ async function main () {
|
|||
// }
|
||||
// ]
|
||||
const upcomingChanges = []
|
||||
|
||||
// add a new entry to the changelog data
|
||||
previousChangelog.unshift(
|
||||
{
|
||||
date: todayString,
|
||||
schemaChanges: [
|
||||
{
|
||||
title: 'The GraphQL schema includes these changes:',
|
||||
changes: formattedChanges
|
||||
}
|
||||
],
|
||||
previewChanges: previewChanges,
|
||||
upcomingChanges: upcomingChanges
|
||||
}
|
||||
)
|
||||
|
||||
// rewrite the updated changelog
|
||||
fs.writeFileSync('lib/graphql/static/changelog.json', JSON.stringify(previousChangelog, null, 2))
|
||||
return changelogEntry
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function segmentPreviewChanges(changesToReport) {
|
||||
// TODO: read the previews yaml file and
|
||||
// split the list of changes based on whether the change's path
|
||||
// (or any "parents" in the change's path) are in a preview.
|
||||
// See: https://github.com/github/graphql-docs/blob/master/lib/graphql_docs/update_internal_developer/change_log.rb#L230
|
||||
return { schemaChangesToReport: changesToReport, previewChangesToReport: [] }
|
||||
}
|
||||
|
||||
const CHANGES_TO_REPORT = [
|
||||
ChangeType.FieldArgumentDefaultChanged,
|
||||
ChangeType.FieldArgumentTypeChanged,
|
||||
ChangeType.EnumValueRemoved,
|
||||
ChangeType.EnumValueAdded,
|
||||
ChangeType.FieldRemoved,
|
||||
ChangeType.FieldAdded,
|
||||
ChangeType.FieldTypeChanged,
|
||||
ChangeType.FieldArgumentAdded,
|
||||
ChangeType.FieldArgumentRemoved,
|
||||
ChangeType.ObjectTypeInterfaceAdded,
|
||||
ChangeType.ObjectTypeInterfaceRemoved,
|
||||
ChangeType.InputFieldRemoved,
|
||||
ChangeType.InputFieldAdded,
|
||||
ChangeType.InputFieldDefaultValueChanged,
|
||||
ChangeType.InputFieldTypeChanged,
|
||||
ChangeType.TypeRemoved,
|
||||
ChangeType.TypeAdded,
|
||||
ChangeType.TypeKindChanged,
|
||||
ChangeType.UnionMemberRemoved,
|
||||
ChangeType.UnionMemberAdded,
|
||||
ChangeType.SchemaQueryTypeChanged,
|
||||
ChangeType.SchemaMutationTypeChanged,
|
||||
ChangeType.SchemaSubscriptionTypeChanged,
|
||||
]
|
||||
|
||||
const CHANGES_TO_IGNORE = [
|
||||
ChangeType.FieldArgumentDescriptionChanged,
|
||||
ChangeType.DirectiveRemoved,
|
||||
ChangeType.DirectiveAdded,
|
||||
ChangeType.DirectiveDescriptionChanged,
|
||||
ChangeType.DirectiveLocationAdded,
|
||||
ChangeType.DirectiveLocationRemoved,
|
||||
ChangeType.DirectiveArgumentAdded,
|
||||
ChangeType.DirectiveArgumentRemoved,
|
||||
ChangeType.DirectiveArgumentDescriptionChanged,
|
||||
ChangeType.DirectiveArgumentDefaultValueChanged,
|
||||
ChangeType.DirectiveArgumentTypeChanged,
|
||||
ChangeType.EnumValueDescriptionChanged,
|
||||
ChangeType.EnumValueDeprecationReasonChanged,
|
||||
ChangeType.EnumValueDeprecationReasonAdded,
|
||||
ChangeType.EnumValueDeprecationReasonRemoved,
|
||||
ChangeType.FieldDescriptionChanged,
|
||||
ChangeType.FieldDescriptionAdded,
|
||||
ChangeType.FieldDescriptionRemoved,
|
||||
ChangeType.FieldDeprecationAdded,
|
||||
ChangeType.FieldDeprecationRemoved,
|
||||
ChangeType.FieldDeprecationReasonChanged,
|
||||
ChangeType.FieldDeprecationReasonAdded,
|
||||
ChangeType.FieldDeprecationReasonRemoved,
|
||||
ChangeType.InputFieldDescriptionAdded,
|
||||
ChangeType.InputFieldDescriptionRemoved,
|
||||
ChangeType.InputFieldDescriptionChanged,
|
||||
ChangeType.TypeDescriptionChanged,
|
||||
ChangeType.TypeDescriptionRemoved,
|
||||
ChangeType.TypeDescriptionAdded,
|
||||
]
|
||||
|
||||
|
||||
|
||||
module.exports = { createChangelogEntry }
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`creating a changelog from old schema and new schema finds a diff of schema changes, upcoming changes, and preview changes 1`] = `
|
||||
Object {
|
||||
"date": "2020-11-20",
|
||||
"previewChanges": Array [],
|
||||
"schemaChanges": Array [
|
||||
Object {
|
||||
"changes": Array [
|
||||
"Field \`removedField\` was removed from object type \`Query\`",
|
||||
"Type for argument \`argumentMadeRequired\` on field \`Query.argumentsField\` changed from \`Int\` to \`Int!\`",
|
||||
"Type for argument \`argumentMadeOptional\` on field \`Query.argumentsField\` changed from \`Int!\` to \`Int\`",
|
||||
"Argument \`removedRequiredArgument: Int!\` was removed from field \`Query.argumentsField\`",
|
||||
"Argument \`removedOptionalArgument: Int!\` was removed from field \`Query.argumentsField\`",
|
||||
],
|
||||
"title": "The GraphQL schema includes these changes:",
|
||||
},
|
||||
],
|
||||
"upcomingChanges": Array [],
|
||||
}
|
||||
`;
|
|
@ -0,0 +1,42 @@
|
|||
const { createChangelogEntry } = require('../../script/graphql/build-changelog')
|
||||
|
||||
describe('creating a changelog from old schema and new schema', () => {
|
||||
it('finds a diff of schema changes, upcoming changes, and preview changes', async () => {
|
||||
const oldSchemaString = `
|
||||
type Query {
|
||||
stableField: String
|
||||
removedField: Boolean
|
||||
argumentsField(
|
||||
removedRequiredArgument: Int!
|
||||
removedOptionalArgument: Int!
|
||||
argumentMadeRequired: Int
|
||||
argumentMadeOptional: Int!
|
||||
): String
|
||||
}
|
||||
`
|
||||
|
||||
const newSchemaString = `
|
||||
type Query {
|
||||
stableField: String
|
||||
argumentsField(
|
||||
argumentMadeRequired: Int!
|
||||
argumentMadeOptional: Int
|
||||
): String
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
const entry = await createChangelogEntry(oldSchemaString, newSchemaString)
|
||||
expect(entry).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('returns null when there isnt any difference', async () => {
|
||||
const schemaString = `
|
||||
type Query {
|
||||
i: Int!
|
||||
}`
|
||||
|
||||
const nullEntry = await createChangelogEntry(schemaString, schemaString)
|
||||
expect(nullEntry).toBeNull()
|
||||
})
|
||||
})
|
Загрузка…
Ссылка в новой задаче