diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index fea996b03b..6359493d4b 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -278,6 +278,8 @@ sqlite squidfunk src stdout +stringify +stringified subcomponent subcomponents subkey diff --git a/plugins/catalog-backend/migrations/20220222164811_reprocess_for_relation_refs.js b/plugins/catalog-backend/migrations/20220222164811_reprocess_for_relation_refs.js new file mode 100644 index 0000000000..f4be2172a0 --- /dev/null +++ b/plugins/catalog-backend/migrations/20220222164811_reprocess_for_relation_refs.js @@ -0,0 +1,31 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // Make sure to reprocess everything, to make sure that relations have a targetRef produced + await knex('refresh_state').update({ + result_hash: '', + next_update_at: knex.fn.now(), + }); + await knex('final_entities').update({ hash: '' }); +}; + +exports.down = async function down() {}; diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts index 3b20282d78..f8b68bebc5 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts @@ -211,11 +211,11 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { for (const entity of entities) { if (entity.relations) { for (const relation of entity.relations) { - if (!relation.targetRef) { + if (!relation.targetRef && relation.target) { // This is the case where an old-form entity, not yet stitched with // the updated code, was in the database relation.targetRef = stringifyEntityRef(relation.target); - } else if (!relation.target) { + } else if (!relation.target && relation.targetRef) { // This is the case where a new-form entity, stitched with the // updated code, was in the database but we still want to produce // the old data shape as well for compatibility reasons diff --git a/plugins/catalog-backend/src/stitching/Stitcher.ts b/plugins/catalog-backend/src/stitching/Stitcher.ts index 018e223e46..37b86fef46 100644 --- a/plugins/catalog-backend/src/stitching/Stitcher.ts +++ b/plugins/catalog-backend/src/stitching/Stitcher.ts @@ -18,6 +18,7 @@ import { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from '@backstage/catalog-client import { AlphaEntity, parseEntityRef, + EntityRelation, EntityStatusItem, } from '@backstage/catalog-model'; import { SerializedError, stringifyError } from '@backstage/errors'; @@ -183,8 +184,9 @@ export class Stitcher { ); entity.relations = uniqueRelationRows .filter(row => row.relationType /* exclude null row, if relevant */) - .map(row => ({ + .map(row => ({ type: row.relationType!, + // TODO(freben): This field is deprecated and should be removed in a future release target: parseEntityRef(row.relationTarget!), targetRef: row.relationTarget!, }));