From a93fd63cb710e7c2ece5613b06ba650b8e588ece Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Wed, 5 Aug 2020 03:14:28 +0200 Subject: [PATCH 1/5] Update adding-templates.md --- docs/features/software-templates/adding-templates.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/features/software-templates/adding-templates.md b/docs/features/software-templates/adding-templates.md index e929ec4a97..1ba9668352 100644 --- a/docs/features/software-templates/adding-templates.md +++ b/docs/features/software-templates/adding-templates.md @@ -10,11 +10,11 @@ A simple `template.yaml` definition might look something like this: apiVersion: backstage.io/v1alpha1 kind: Template metadata: - # unique name per namespace for the template + # unique name per namespace for the template name: react-ssr-template - # title of the template + # title of the template title: React SSR Template - # a description of the template + # a description of the template description: Next.js application skeleton for creating isomorphic web applications. # some tags to display in the frontend tags: @@ -23,11 +23,11 @@ metadata: spec: # which templater key to use in the templaters builder templater: cookiecutter - # what does this template create + # what does this template create type: website - # if the template is not in the current directory where this definition is kept then specfiy + # if the template is not in the current directory where this definition is kept then specfiy path: './template' - # the schema for the form which is displayed in the frontend. + # the schema for the form which is displayed in the frontend. # should follow JSON schema for forms: https://jsonforms.io/ schema: required: From e2383a399d0859e2c7322f6abdf7ea9eb28de63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 5 Aug 2020 16:50:49 +0200 Subject: [PATCH 2/5] fix(catalog-backend): properly deduplicate location logs --- ...904_location_update_log_duplication_fix.js | 75 +++++++++++++++++++ .../catalog/DatabaseLocationsCatalog.test.ts | 29 +++++++ .../src/database/CommonDatabase.ts | 2 - 3 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 plugins/catalog-backend/migrations/20200805163904_location_update_log_duplication_fix.js diff --git a/plugins/catalog-backend/migrations/20200805163904_location_update_log_duplication_fix.js b/plugins/catalog-backend/migrations/20200805163904_location_update_log_duplication_fix.js new file mode 100644 index 0000000000..aa59b54ac8 --- /dev/null +++ b/plugins/catalog-backend/migrations/20200805163904_location_update_log_duplication_fix.js @@ -0,0 +1,75 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 + */ +exports.up = function up(knex) { + return knex.schema + .dropTable('location_update_log') + .createTable('location_update_log', table => { + table.bigIncrements('id').primary(); // instead of uuid, so we can MAX it + table.enum('status', ['success', 'fail']).notNullable(); + table.dateTime('created_at').defaultTo(knex.fn.now()).notNullable(); + table.string('message'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .onUpdate('CASCADE') + .onDelete('CASCADE'); + table.string('entity_name').nullable(); + }).raw(` + DROP VIEW location_update_log_latest; + `).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(id) AS MAXID + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.id = t2.MAXID + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); +}; + +/** + * @param {import('knex')} knex + */ +exports.down = function down(knex) { + return knex.schema.raw(` + DROP VIEW location_update_log_latest; + `).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(created_at) AS MAXDATE + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.created_at = t2.MAXDATE + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); +}; diff --git a/plugins/catalog-backend/src/catalog/DatabaseLocationsCatalog.test.ts b/plugins/catalog-backend/src/catalog/DatabaseLocationsCatalog.test.ts index 8c7897fa2c..679e5b43c1 100644 --- a/plugins/catalog-backend/src/catalog/DatabaseLocationsCatalog.test.ts +++ b/plugins/catalog-backend/src/catalog/DatabaseLocationsCatalog.test.ts @@ -39,4 +39,33 @@ describe('DatabaseLocationsCatalog', () => { expect.objectContaining({ data: location }), ]); }); + + it('does not return duplicates of rows because of logs', async () => { + const location1 = { + id: 'dd12620d-0436-422f-93bd-929aa0788123', + type: 'valid_type', + target: 'valid_target1', + }; + const location2 = { + id: '1a89c479-1a33-4f27-8927-6090ba488c42', + type: 'valid_type', + target: 'valid_target2', + }; + await expect(catalog.addLocation(location1)).resolves.toEqual(location1); + await expect(catalog.addLocation(location2)).resolves.toEqual(location2); + await expect( + catalog.logUpdateSuccess(location1.id), + ).resolves.toBeUndefined(); + await expect( + catalog.logUpdateSuccess(location1.id), + ).resolves.toBeUndefined(); + const locations = await catalog.locations(); + expect(locations.length).toBe(2); + expect(locations).toEqual( + expect.arrayContaining([ + expect.objectContaining({ data: location1 }), + expect.objectContaining({ data: location2 }), + ]), + ); + }); }); diff --git a/plugins/catalog-backend/src/database/CommonDatabase.ts b/plugins/catalog-backend/src/database/CommonDatabase.ts index c860f52d1e..0c56ca4370 100644 --- a/plugins/catalog-backend/src/database/CommonDatabase.ts +++ b/plugins/catalog-backend/src/database/CommonDatabase.ts @@ -29,7 +29,6 @@ import { } from '@backstage/catalog-model'; import Knex from 'knex'; import lodash from 'lodash'; -import { v4 as uuidv4 } from 'uuid'; import type { Logger } from 'winston'; import { buildEntitySearch } from './search'; import type { @@ -347,7 +346,6 @@ export class CommonDatabase implements Database { return this.database( 'location_update_log', ).insert({ - id: uuidv4(), status, location_id: locationId, entity_name: entityName, From b746ffdb7c66a984084c2395f1a6feb4e30c615b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Aug 2020 12:58:07 +0200 Subject: [PATCH 3/5] Create CHANGELOG.md --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..29cae2be34 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,23 @@ +# Backstage Changelog + +This is a best-effort changelog where we manually collect breaking changes. It is not an exhaustive list of all changes or even features added. + +If you encounter issues while upgrading to a newer version, don't hesitate to reach out on Discord or open an issue! + +## Next Release + +> Collect changes for the next release below + +### @backstage/catalog-backend + +- Fixed and issue with duplicated location logs. Applying the database migrations from this fix will clear the existing migration logs. https://github.com/spotify/backstage/pull/1836 + +## v0.1.1-alpha.17 + +### @backstage/techdocs-backend + +- The techdocs backend now requires more configuration to be supplied when creating the router. See [packages/backend/src/plugins/techdocs.ts](https://github.com/spotify/backstage/blob/0201fd9b4a52429519dd59e9184106ba69456deb/packages/backend/src/plugins/techdocs.ts#L42) for an example. https://github.com/spotify/backstage/pull/1736 + +### @backstage/cli + +- The `create-app` command was moved out from the CLI to a standalone package. It's now invoked with `npx @backstage/create-app` instead. https://github.com/spotify/backstage/pull/1745 From 8eab652ecd9ef627364a57d86becf1794b8b6b14 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Aug 2020 14:04:16 +0200 Subject: [PATCH 4/5] CHANGELOG: Fixed and --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29cae2be34..47baf38e6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ If you encounter issues while upgrading to a newer version, don't hesitate to re ### @backstage/catalog-backend -- Fixed and issue with duplicated location logs. Applying the database migrations from this fix will clear the existing migration logs. https://github.com/spotify/backstage/pull/1836 +- Fixed an issue with duplicated location logs. Applying the database migrations from this fix will clear the existing migration logs. https://github.com/spotify/backstage/pull/1836 ## v0.1.1-alpha.17 From 6a49985c87d44018e1e69a9682d010ea9b63d207 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 6 Aug 2020 14:06:31 +0200 Subject: [PATCH 5/5] CHANGELOG: link to things --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47baf38e6c..b938542b54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ This is a best-effort changelog where we manually collect breaking changes. It is not an exhaustive list of all changes or even features added. -If you encounter issues while upgrading to a newer version, don't hesitate to reach out on Discord or open an issue! +If you encounter issues while upgrading to a newer version, don't hesitate to reach out on [Discord](https://discord.gg/EBHEGzX) or [open an issue](https://github.com/spotify/backstage/issues/new/choose)! ## Next Release