feat: schema version promotion#8031
Conversation
| ALTER COLUMN IF EXISTS "action_id" DROP NOT NULL | ||
| , ADD COLUMN IF NOT EXISTS "origin" jsonb NULL |
There was a problem hiding this comment.
There is now no longer "one" single action that caused a schema version.
Instead we have now a origin column that stores the information (subgraph/schema publish; subgraph removal; schema promotion) in a more flexible way.
| ALTER TABLE "schema_versions" | ||
| ALTER COLUMN IF EXISTS "action_id" DROP NOT NULL | ||
| , ADD COLUMN IF NOT EXISTS "origin" jsonb NULL | ||
| , ADD COLUMN IF NOT EXISTS "supergraph_changes" jsonb NULL |
There was a problem hiding this comment.
We store the public schema changes in a separate table schema_version_changes. However, we do not do anything with that table aside from loading the rows. No custom indices etc.
Thus I made the decision to add the column to store supergraph changes to the schema_versions table directly.
| log: RegistryLog! | ||
| @tag(name: "public") | ||
| @deprecated(reason: "Please use 'SchemaVersion.origin' instead.") |
There was a problem hiding this comment.
Note: I plan to remove this field as part of this pull request. I just deprecated it for now as it is used in unit tests.
Conditional breaking changes says its safe to remove it.
|
🐋 This PR was built and pushed to the following Docker images: Targets: Platforms: Image Tag: |
There was a problem hiding this comment.
Code Review
This pull request introduces a schema version promotion feature, allowing users to promote a schema version from one target to another within a project. It includes a new database migration, GraphQL schema updates for the schemaVersionPromote mutation and PromotionSchemaLog type, and significant logic in SchemaPublisher and SchemaVersionStore to handle the promotion process and track version origins. Feedback includes identifying a missing crypto import that will cause runtime errors, a typo in a SQL string, and unsafe array access. Additionally, there are suggestions to update an incorrect migration comment, reconsider the use of a dummy field in the GraphQL schema, and evaluate if STITCHING projects should also support this feature.
| throw new Error('INVARIANT: Remove logs require a service name.'); | ||
| } | ||
| // Note: we seed the ID here so we do not need to map some more within the logic within `SchemaVersions.promoteSchemaVersionToTarget` | ||
| const logId = crypto.randomUUID(); |
There was a problem hiding this comment.
| /** | ||
| * Adds an expiration date to tokens. This expiration doesn't need to | ||
| * be an index since we're always looking up by ID and then can verify | ||
| * the timestamp via a filter. Since these lookups are always be done | ||
| * via provider methods and not via a raw table query, this is safe. | ||
| */ |
| """ | ||
| The origin of this schema log promotion. | ||
| """ | ||
| _: Boolean! @tag(name: "public") |
There was a problem hiding this comment.
| }), | ||
| ]); | ||
|
|
||
| if (project.type !== Types.ProjectType.FEDERATION) { |
| const schemas = await this.schemaVersions.getSchemasBySchemaVersionId(schemaVersion.id); | ||
| actionId = schemas[0].id; |
There was a problem hiding this comment.
Unsafe access to schemas[0]. If getSchemasBySchemaVersionId returns an empty array, this will throw a runtime error. It is safer to check if the array has elements before accessing them.
const schemas = await this.schemaVersions.getSchemasBySchemaVersionId(schemaVersion.id);
if (schemas.length === 0) {
throw new Error('INVARIANT: No schemas found for the version');
}
actionId = schemas[0].id;91ca78a to
05a3f05
Compare
f15a85c to
c0f20b4
Compare
c0f20b4 to
9d6cac5
Compare
| ALTER COLUMN "action_id" DROP NOT NULL | ||
| , ADD COLUMN IF NOT EXISTS "origin" jsonb NULL | ||
| , ADD COLUMN IF NOT EXISTS "supergraph_changes" jsonb NULL | ||
| , ADD COLUMN IF NOT EXISTS "meta" jsonb NULL |
There was a problem hiding this comment.
This column stores additional user-provided metadata such as commit and author. Previously this was exclusively stored on the schema_log. However, since now a schema version is no longer exclusively triggered by "one" schema_log, we need to store that metadata on the schema version directly in order to make other existing functionality still work as expected.
| ALTER TABLE "schema_version_to_log" | ||
| ADD COLUMN IF NOT EXISTS type hive_subgraph_log_type DEFAULT NULL | ||
| , ADD COLUMN IF NOT EXISTS "previous_action_id" UUID DEFAULT NULL REFERENCES "schema_log"("id") ON DELETE CASCADE | ||
| , ADD COLUMN IF NOT EXISTS "schema_changes" JSONB DEFAULT NULL | ||
| , ADD COLUMN IF NOT EXISTS "subgraph_name" TEXT NULL | ||
| ; |
There was a problem hiding this comment.
This type stores now more complex information that serves the purpose of tracking how the subgraphs changed between schema versions.
9867645 to
308bfea
Compare
Background
Closes #4021
Description
Introduces functionality for promoting a schema version from one target to another target (or the same target), making it the latest version within that target.
This enables workflows such as:
Alongside a new CLI command for performing these promotions this change also comes along a new UI for schema versions with more insights into the individual changes of the subgraphs.