Skip to content

Commit 7e3ad57

Browse files
authored
Merge branch 'main' into extensions-bug-fixes
2 parents 4995b15 + 80025a7 commit 7e3ad57

File tree

31 files changed

+2215
-1949
lines changed

31 files changed

+2215
-1949
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: Detect and propose Renovate presets for new workspaces
2+
3+
on:
4+
schedule:
5+
- cron: "0 6 * * 1" # Every Monday at 06:00 UTC
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
12+
concurrency:
13+
group: new-workspace-presets
14+
cancel-in-progress: false
15+
16+
jobs:
17+
prepare:
18+
name: Detect uncovered workspaces
19+
runs-on: ubuntu-latest
20+
outputs:
21+
workspaces: ${{ steps.detect.outputs.workspaces }}
22+
steps:
23+
- name: Harden Runner
24+
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
25+
with:
26+
egress-policy: audit
27+
28+
- name: Checkout main
29+
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
30+
with:
31+
ref: main
32+
token: ${{ secrets.RHDH_BOT_TOKEN }}
33+
fetch-depth: 1
34+
35+
- name: Set up Node
36+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
37+
with:
38+
node-version: 22
39+
40+
- name: Install dependencies
41+
run: yarn install --immutable
42+
43+
- name: Detect new workspaces
44+
id: detect
45+
run: echo "workspaces=$(node scripts/ci/detect-new-workspaces.js --list | jq -c .)" >> $GITHUB_OUTPUT
46+
47+
propose:
48+
name: Propose preset for workspace
49+
runs-on: ubuntu-latest
50+
needs: prepare
51+
if: needs.prepare.outputs.workspaces != '[]' && needs.prepare.outputs.workspaces != ''
52+
strategy:
53+
matrix:
54+
workspace: ${{ fromJSON(needs.prepare.outputs.workspaces) }}
55+
steps:
56+
- name: Harden Runner
57+
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
58+
with:
59+
egress-policy: audit
60+
61+
- name: Checkout main
62+
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
63+
with:
64+
ref: main
65+
token: ${{ secrets.RHDH_BOT_TOKEN }}
66+
fetch-depth: 1
67+
68+
- name: Set up Node
69+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
70+
with:
71+
node-version: 22
72+
73+
- name: Install dependencies
74+
run: yarn install --immutable
75+
76+
- name: Apply changes for workspace
77+
id: apply
78+
run: node scripts/ci/detect-new-workspaces.js --apply "${{ matrix.workspace }}"
79+
80+
- name: Create Pull Request
81+
uses: peter-evans/create-pull-request@b1ddad2c994a25fbc81a28b3ec0e368bb2021c50 # v6.0.0
82+
with:
83+
token: ${{ secrets.RHDH_BOT_TOKEN }}
84+
base: main
85+
branch: automation/add-renovate-presets-${{ matrix.workspace }}
86+
commit-message: "chore: add Renovate presets for ${{ matrix.workspace }}"
87+
title: "chore: add Renovate presets for ${{ matrix.workspace }}"
88+
body: |
89+
This PR adds Renovate presets for the new `${{ matrix.workspace }}` workspace.
90+
91+
Extends: base minor/patch/devdependency presets.
92+
93+
Created by [Detect New Workspace ${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
94+
signoff: true
95+
add-paths: |
96+
.github/renovate-presets/workspace/*.json
97+
.github/renovate.json
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*
2+
* Copyright Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import fs from 'fs';
17+
import path from 'path';
18+
import { format as prettierFormat } from 'prettier';
19+
20+
const workspacesDir = path.resolve('workspaces');
21+
const presetsDir = path.resolve('.github', 'renovate-presets', 'workspace');
22+
const renovateJsonPath = path.resolve('.github', 'renovate.json');
23+
24+
function listWorkspaceNames() {
25+
if (!fs.existsSync(workspacesDir)) return [];
26+
return fs
27+
.readdirSync(workspacesDir, { withFileTypes: true })
28+
.filter(dirent => dirent.isDirectory())
29+
.map(dirent => dirent.name)
30+
.filter(name => name !== 'noop')
31+
.sort();
32+
}
33+
34+
function isWorkspaceCovered(workspaceName) {
35+
const presetFile = path.join(
36+
presetsDir,
37+
`rhdh-${workspaceName}-presets.json`,
38+
);
39+
return fs.existsSync(presetFile);
40+
}
41+
42+
function toTitleCase(source) {
43+
return source
44+
.split(/[-_ ]+/)
45+
.filter(Boolean)
46+
.map(token => token.charAt(0).toLocaleUpperCase('en-US') + token.slice(1))
47+
.join(' ');
48+
}
49+
50+
async function ensureRenovateExtends(presetRef) {
51+
let content = fs.readFileSync(renovateJsonPath, 'utf8');
52+
53+
if (content.includes(`"${presetRef}"`)) {
54+
return false;
55+
}
56+
57+
const descIndex = content.indexOf('"all RHDH Plugins workspaces"');
58+
if (descIndex === -1) {
59+
throw new Error('Could not find "all RHDH Plugins workspaces" rule');
60+
}
61+
62+
const extendsIndex = content.indexOf('"extends":', descIndex);
63+
const arrayStart = content.indexOf('[', extendsIndex);
64+
const arrayEnd = content.indexOf(']', arrayStart);
65+
66+
if (extendsIndex === -1 || arrayStart === -1 || arrayEnd === -1) {
67+
throw new Error('Could not find extends array');
68+
}
69+
70+
const before = content.substring(0, arrayEnd).trimEnd();
71+
const after = content.substring(arrayEnd);
72+
content = `${before},\n "${presetRef}"\n ${after}`;
73+
74+
fs.writeFileSync(renovateJsonPath, content, 'utf8');
75+
return true;
76+
}
77+
78+
if (!fs.existsSync(presetsDir)) fs.mkdirSync(presetsDir, { recursive: true });
79+
80+
function buildPresetJson(workspaceName) {
81+
const displayName = toTitleCase(workspaceName.replace(/^rhdh-/, ''));
82+
return {
83+
packageRules: [
84+
{
85+
description: `all ${displayName} minor updates`,
86+
matchFileNames: [`workspaces/${workspaceName}/**`],
87+
extends: [
88+
`github>redhat-developer/rhdh-plugins//.github/renovate-presets/base/rhdh-minor-presets(${displayName})`,
89+
],
90+
addLabels: ['team/rhdh', `${workspaceName}`],
91+
},
92+
{
93+
description: `all ${displayName} patch updates`,
94+
matchFileNames: [`workspaces/${workspaceName}/**`],
95+
extends: [
96+
`github>redhat-developer/rhdh-plugins//.github/renovate-presets/base/rhdh-patch-presets(${displayName})`,
97+
],
98+
addLabels: ['team/rhdh', `${workspaceName}`],
99+
},
100+
{
101+
description: `all ${displayName} dev dependency updates`,
102+
matchFileNames: [`workspaces/${workspaceName}/**`],
103+
extends: [
104+
`github>redhat-developer/rhdh-plugins//.github/renovate-presets/base/rhdh-devdependency-presets(${displayName})`,
105+
],
106+
addLabels: ['team/rhdh', `${workspaceName}`],
107+
},
108+
],
109+
};
110+
}
111+
112+
function findUncoveredWorkspaces() {
113+
return listWorkspaceNames().filter(ws => !isWorkspaceCovered(ws));
114+
}
115+
116+
const argv = process.argv.slice(2);
117+
switch (argv[0]) {
118+
case '--apply': {
119+
const ws = argv[1];
120+
if (!ws) {
121+
console.error('ERROR: --apply requires a workspace name');
122+
process.exit(2);
123+
}
124+
if (isWorkspaceCovered(ws)) {
125+
console.log(JSON.stringify({ workspace: ws, skipped: true }));
126+
process.exit(0);
127+
}
128+
129+
const presetFilePath = path.join(presetsDir, `rhdh-${ws}-presets.json`);
130+
const presetJson = buildPresetJson(ws);
131+
const formattedPreset = await prettierFormat(JSON.stringify(presetJson), {
132+
parser: 'json',
133+
});
134+
fs.writeFileSync(presetFilePath, formattedPreset, 'utf8');
135+
const presetRef = `github>redhat-developer/rhdh-plugins//.github/renovate-presets/workspace/rhdh-${ws}-presets`;
136+
await ensureRenovateExtends(presetRef);
137+
if (process.env.GITHUB_OUTPUT) {
138+
fs.appendFileSync(process.env.GITHUB_OUTPUT, `workspace=${ws}\n`);
139+
}
140+
console.log(JSON.stringify({ workspace: ws }));
141+
break;
142+
}
143+
case '--list': {
144+
const queue = findUncoveredWorkspaces();
145+
console.log(JSON.stringify(queue));
146+
break;
147+
}
148+
default: {
149+
console.error(
150+
`Unknown command: ${argv[0]}. Use --list (default) or --apply <workspace>.`,
151+
);
152+
break;
153+
}
154+
}

workspaces/orchestrator/.changeset/eighty-cobras-wink.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

workspaces/orchestrator/.changeset/rare-apricots-suffer.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

workspaces/orchestrator/.changeset/slimy-impalas-fold.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

workspaces/orchestrator/.changeset/spotty-rivers-learn.md

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"version": "1.39.1"
2+
"version": "1.42.5"
33
}

workspaces/orchestrator/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"scripts": {
99
"tsc": "tsc",
1010
"dev": "yarn workspaces foreach -A --include backend --include app --parallel --jobs unlimited -v -i run start",
11+
"start": "backstage-cli repo start",
1112
"dev:debug": "LOG_LEVEL=debug yarn dev",
1213
"tsc:full": "tsc --skipLibCheck true --incremental false",
1314
"build:all": "backstage-cli repo build --all",
@@ -38,9 +39,9 @@
3839
"directory": "workspaces/orchestrator"
3940
},
4041
"devDependencies": {
41-
"@backstage/cli": "^0.32.1",
42+
"@backstage/cli": "^0.34.1",
4243
"@backstage/e2e-test-utils": "^0.1.1",
43-
"@backstage/repo-tools": "^0.13.4",
44+
"@backstage/repo-tools": "^0.15.1",
4445
"@changesets/cli": "^2.27.1",
4546
"@ianvs/prettier-plugin-sort-imports": "^4.4.0",
4647
"knip": "^5.40.0",

workspaces/orchestrator/packages/app/package.json

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,31 @@
2020
},
2121
"dependencies": {
2222
"@backstage-community/plugin-rbac": "^1.33.2",
23-
"@backstage/app-defaults": "^1.6.2",
24-
"@backstage/catalog-model": "^1.7.4",
25-
"@backstage/cli": "^0.32.1",
26-
"@backstage/core-app-api": "^1.17.0",
27-
"@backstage/core-components": "0.17.2",
28-
"@backstage/core-plugin-api": "^1.10.7",
29-
"@backstage/integration-react": "^1.2.7",
30-
"@backstage/plugin-api-docs": "^0.12.7",
31-
"@backstage/plugin-catalog": "^1.30.0",
32-
"@backstage/plugin-catalog-common": "^1.1.4",
33-
"@backstage/plugin-catalog-graph": "^0.4.19",
34-
"@backstage/plugin-catalog-import": "^0.13.0",
35-
"@backstage/plugin-catalog-react": "^1.18.0",
36-
"@backstage/plugin-notifications": "^0.5.5",
37-
"@backstage/plugin-org": "^0.6.39",
38-
"@backstage/plugin-permission-react": "^0.4.34",
39-
"@backstage/plugin-scaffolder": "^1.31.0",
40-
"@backstage/plugin-search": "^1.4.26",
41-
"@backstage/plugin-search-react": "^1.9.0",
42-
"@backstage/plugin-signals": "^0.0.19",
43-
"@backstage/plugin-techdocs": "^1.12.6",
44-
"@backstage/plugin-techdocs-module-addons-contrib": "^1.1.24",
45-
"@backstage/plugin-techdocs-react": "^1.2.17",
46-
"@backstage/plugin-user-settings": "^0.8.22",
47-
"@backstage/theme": "^0.6.6",
23+
"@backstage/app-defaults": "^1.6.5",
24+
"@backstage/catalog-model": "^1.7.5",
25+
"@backstage/cli": "^0.34.1",
26+
"@backstage/core-app-api": "^1.18.0",
27+
"@backstage/core-components": "^0.17.5",
28+
"@backstage/core-plugin-api": "^1.10.9",
29+
"@backstage/integration-react": "^1.2.9",
30+
"@backstage/plugin-api-docs": "^0.12.10",
31+
"@backstage/plugin-catalog": "^1.31.2",
32+
"@backstage/plugin-catalog-common": "^1.1.5",
33+
"@backstage/plugin-catalog-graph": "^0.4.22",
34+
"@backstage/plugin-catalog-import": "^0.13.4",
35+
"@backstage/plugin-catalog-react": "^1.20.1",
36+
"@backstage/plugin-notifications": "^0.5.8",
37+
"@backstage/plugin-org": "^0.6.43",
38+
"@backstage/plugin-permission-react": "^0.4.36",
39+
"@backstage/plugin-scaffolder": "^1.34.0",
40+
"@backstage/plugin-search": "^1.4.29",
41+
"@backstage/plugin-search-react": "^1.9.3",
42+
"@backstage/plugin-signals": "^0.0.22",
43+
"@backstage/plugin-techdocs": "^1.14.1",
44+
"@backstage/plugin-techdocs-module-addons-contrib": "^1.1.27",
45+
"@backstage/plugin-techdocs-react": "^1.3.2",
46+
"@backstage/plugin-user-settings": "^0.8.25",
47+
"@backstage/theme": "^0.6.8",
4848
"@mui/icons-material": "5.18.0",
4949
"@mui/lab": "5.0.0-alpha.177",
5050
"@mui/material": "5.18.0",
@@ -61,7 +61,7 @@
6161
"react-use": "^17.4.0"
6262
},
6363
"devDependencies": {
64-
"@backstage/test-utils": "^1.7.8",
64+
"@backstage/test-utils": "^1.7.11",
6565
"@playwright/test": "1.54.2",
6666
"@testing-library/dom": "^9.0.0",
6767
"@testing-library/jest-dom": "^6.0.0",

0 commit comments

Comments
 (0)