From ee3ee0701f76fde985be095cbaebd4f2c3f4420d Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 11:02:00 +0100 Subject: [PATCH 1/7] github-actions: Add assemble release workflow Signed-off-by: Johan Haals --- .github/workflows/assemble-release.yml | 37 ++++++++++++++++ scripts/assemble-manifest.js | 60 ++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 .github/workflows/assemble-release.yml create mode 100755 scripts/assemble-manifest.js diff --git a/.github/workflows/assemble-release.yml b/.github/workflows/assemble-release.yml new file mode 100644 index 0000000000..000e72000b --- /dev/null +++ b/.github/workflows/assemble-release.yml @@ -0,0 +1,37 @@ +name: Assemble release and generate versions file +on: + workflow_dispatch: + inputs: + version: + description: 'Version number' + required: true +jobs: + create-new-version: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Checkout versions + uses: actions/checkout@v2 + with: + repository: backstage/versions + path: versions + token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} + - name: Configure Git + run: | + git config --global user.email noreply@backstage.io + git config --global user.name 'Github versions workflow' + - name: Create release + run: | + node scripts/assemble-manifest.js ${{ github.event.inputs.version }} versions/v1/releases + cd versions + if [[ "${{ github.event.inputs.version }}" == *"next"* ]]; then + echo Updating next tag + rm -f v1/tags/next && ln -s ../releases/${{ github.event.inputs.version }} v1/tags/next + else + echo Updating main tag + rm -f v1/tags/main && ln -s ../releases/${{ github.event.inputs.version }} v1/tags/main + fi + git add . + git commit -am "${{ github.event.inputs.version }}" + git push diff --git a/scripts/assemble-manifest.js b/scripts/assemble-manifest.js new file mode 100755 index 0000000000..118281fb5c --- /dev/null +++ b/scripts/assemble-manifest.js @@ -0,0 +1,60 @@ +#!/usr/bin/env node +/* eslint-disable import/no-extraneous-dependencies */ +/* + * Copyright 2022 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. + */ + +const fs = require('fs-extra'); +const { getPackages } = require('@manypkg/get-packages'); +const path = require('path'); + +async function main() { + const [version, outputPath] = process.argv.slice(2); + if (!version || !outputPath) { + throw new Error('Argument must be script.js '); + } + + const manifestDir = path.resolve(outputPath, version); + if (await fs.pathExists(manifestDir)) { + throw new Error( + `Release manifest path for version ${version} already exists`, + ); + } + + console.log(`Assembling packages for backstage release ${version}`); + const { packages } = await getPackages(path.resolve('.')); + + const versions = packages + .filter( + p => + (p.packageJson.name.startsWith('@backstage/') || + p.packageJson.name.startsWith('@techdocs/')) && + p.packageJson.private === false, + ) + .map(p => { + return { name: p.packageJson.name, version: p.packageJson.version }; + }); + await fs.mkdir(manifestDir); + await fs.writeJSON( + path.resolve(manifestDir, 'manifest.json'), + { packages: versions }, + { spaces: 2 }, + ); +} + +main().catch(error => { + console.error(error.stack); + process.exit(1); +}); From 06f0296caefd45ea07ca5d630c86ba565209f3e6 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 11:54:55 +0100 Subject: [PATCH 2/7] Rename workflow Signed-off-by: Johan Haals --- .../{assemble-release.yml => sync_release-manifest.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{assemble-release.yml => sync_release-manifest.yml} (96%) diff --git a/.github/workflows/assemble-release.yml b/.github/workflows/sync_release-manifest.yml similarity index 96% rename from .github/workflows/assemble-release.yml rename to .github/workflows/sync_release-manifest.yml index 000e72000b..48a0cc12ed 100644 --- a/.github/workflows/assemble-release.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -1,4 +1,4 @@ -name: Assemble release and generate versions file +name: Sync Release Manifest on: workflow_dispatch: inputs: From 19a9c341a7bf66ac91849bccd8230099840c2cf4 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 11:55:24 +0100 Subject: [PATCH 3/7] Output script path in error Signed-off-by: Johan Haals --- scripts/assemble-manifest.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/assemble-manifest.js b/scripts/assemble-manifest.js index 118281fb5c..9d16d83aa0 100755 --- a/scripts/assemble-manifest.js +++ b/scripts/assemble-manifest.js @@ -21,9 +21,9 @@ const { getPackages } = require('@manypkg/get-packages'); const path = require('path'); async function main() { - const [version, outputPath] = process.argv.slice(2); + const [script, version, outputPath] = process.argv.slice(1); if (!version || !outputPath) { - throw new Error('Argument must be script.js '); + throw new Error(`Argument must be ${script} `); } const manifestDir = path.resolve(outputPath, version); From 3b948a982e18b99359a9123d3bf332911f7e647c Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 14:21:53 +0100 Subject: [PATCH 4/7] Move symlinking to script. Require valid semver range Signed-off-by: Johan Haals --- .github/workflows/sync_release-manifest.yml | 9 +------- scripts/assemble-manifest.js | 25 ++++++++++++++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index 48a0cc12ed..e41fc6604a 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -23,15 +23,8 @@ jobs: git config --global user.name 'Github versions workflow' - name: Create release run: | - node scripts/assemble-manifest.js ${{ github.event.inputs.version }} versions/v1/releases + node scripts/assemble-manifest.js ${{ github.event.inputs.version }} cd versions - if [[ "${{ github.event.inputs.version }}" == *"next"* ]]; then - echo Updating next tag - rm -f v1/tags/next && ln -s ../releases/${{ github.event.inputs.version }} v1/tags/next - else - echo Updating main tag - rm -f v1/tags/main && ln -s ../releases/${{ github.event.inputs.version }} v1/tags/main - fi git add . git commit -am "${{ github.event.inputs.version }}" git push diff --git a/scripts/assemble-manifest.js b/scripts/assemble-manifest.js index 9d16d83aa0..09ba3e9329 100755 --- a/scripts/assemble-manifest.js +++ b/scripts/assemble-manifest.js @@ -16,17 +16,21 @@ * limitations under the License. */ +const semver = require('semver'); const fs = require('fs-extra'); const { getPackages } = require('@manypkg/get-packages'); const path = require('path'); async function main() { - const [script, version, outputPath] = process.argv.slice(1); - if (!version || !outputPath) { - throw new Error(`Argument must be ${script} `); + const [script, version] = process.argv.slice(1); + if (!version) { + throw new Error(`Argument must be ${script} `); + } + if (!semver.valid(version)) { + throw new Error(`version '${version}' must be a valid semver`); } - const manifestDir = path.resolve(outputPath, version); + const manifestDir = path.resolve('versions', 'v1', 'releases', version); if (await fs.pathExists(manifestDir)) { throw new Error( `Release manifest path for version ${version} already exists`, @@ -49,9 +53,20 @@ async function main() { await fs.mkdir(manifestDir); await fs.writeJSON( path.resolve(manifestDir, 'manifest.json'), - { packages: versions }, + { releaseVersion: version, packages: versions }, { spaces: 2 }, ); + const tag = version.includes('next') ? 'next' : 'main'; + const tagPath = path.resolve('versions', 'v1', 'tags', tag); + const currentTag = await fs.readJSON(path.resolve(tagPath, 'manifest.json')); + if (semver.gt(currentTag.releaseVersion, version)) { + console.log( + `Skipping update of ${tagPath} since current current ${tag} version is ${currentTag.releaseVersion}`, + ); + return; + } + await fs.remove(tagPath); + await fs.ensureSymlink(path.join('..', 'releases', version), tagPath); } main().catch(error => { From 6880c9ac5349057bc0b4ec848db238f27e05d411 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 16:23:24 +0100 Subject: [PATCH 5/7] ensure that tagPath exists Signed-off-by: Johan Haals --- scripts/assemble-manifest.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/assemble-manifest.js b/scripts/assemble-manifest.js index 09ba3e9329..eb53eb0eaf 100755 --- a/scripts/assemble-manifest.js +++ b/scripts/assemble-manifest.js @@ -50,7 +50,7 @@ async function main() { .map(p => { return { name: p.packageJson.name, version: p.packageJson.version }; }); - await fs.mkdir(manifestDir); + await fs.ensureDir(manifestDir); await fs.writeJSON( path.resolve(manifestDir, 'manifest.json'), { releaseVersion: version, packages: versions }, @@ -58,12 +58,16 @@ async function main() { ); const tag = version.includes('next') ? 'next' : 'main'; const tagPath = path.resolve('versions', 'v1', 'tags', tag); - const currentTag = await fs.readJSON(path.resolve(tagPath, 'manifest.json')); - if (semver.gt(currentTag.releaseVersion, version)) { - console.log( - `Skipping update of ${tagPath} since current current ${tag} version is ${currentTag.releaseVersion}`, + if (await fs.pathExists(tagPath)) { + const currentTag = await fs.readJSON( + path.resolve(tagPath, 'manifest.json'), ); - return; + if (semver.gt(currentTag.releaseVersion, version)) { + console.log( + `Skipping update of ${tagPath} since current current ${tag} version is ${currentTag.releaseVersion}`, + ); + process.exit(1); + } } await fs.remove(tagPath); await fs.ensureSymlink(path.join('..', 'releases', version), tagPath); From e77926db8419d7d56acd92da218bbeaa27ac1ddd Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 16:24:53 +0100 Subject: [PATCH 6/7] checkout tag, yarn install Signed-off-by: Johan Haals --- .github/workflows/sync_release-manifest.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index e41fc6604a..31866a5279 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -11,6 +11,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 + with: + ref: {{ github.event.inputs.version }} + - name: Install dependencies + run: yarn install - name: Checkout versions uses: actions/checkout@v2 with: From 232f66cfbf183fdce5494477f735fd899fe9afdb Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 16:36:50 +0100 Subject: [PATCH 7/7] fix ref format Signed-off-by: Johan Haals --- .github/workflows/sync_release-manifest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index 31866a5279..e8a50904d0 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout uses: actions/checkout@v2 with: - ref: {{ github.event.inputs.version }} + ref: ${{ github.event.inputs.version }} - name: Install dependencies run: yarn install - name: Checkout versions