-
Notifications
You must be signed in to change notification settings - Fork 297
chore: Automate RC creation [WPB-22028] #19812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 19 commits
92d866e
59de699
bd2f77a
d70f2fa
6dcc1a6
1d5c874
a092a94
220d86d
7011bd3
3cd71f6
d09efa4
34b18c7
14ecacd
f968d66
4544833
75705f3
9b6e8dc
0315fc1
44c5de1
c5d9ddd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,72 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Prepare RC | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rc_branch: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'RC branch name (e.g. rc/2025-11-27)' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| prepare_rc: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Ensure workflow is run from dev branch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: github.ref_name != 'dev' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "This workflow can only be run when 'dev' is selected as the workflow ref (current: '${{ github.ref_name }}')." >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout dev | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref: dev | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Setup Node.js | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-node@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node-version: 22.x | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node-version: 22.x | |
| node-version: 18.16.x |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Important] Missing error handling for npm view commands. If any package doesn't exist or the registry is unreachable, the command will fail silently or with unclear errors due to command substitution happening before yarn add executes.
Consider adding explicit checks or error handling:
- name: Update @wireapp/* to latest stable
run: |
set -euo pipefail
# Fetch all versions first to fail fast if registry is unreachable
STORE_ENGINE=$(npm view @wireapp/store-engine dist-tags.latest) || exit 1
COMMONS=$(npm view @wireapp/commons dist-tags.latest) || exit 1
# ... repeat for other packages
yarn add \
@wireapp/store-engine@${STORE_ENGINE} \
@wireapp/commons@${COMMONS} \
# ... etc| yarn add \ | |
| @wireapp/store-engine@$(npm view @wireapp/store-engine dist-tags.latest) \ | |
| @wireapp/commons@$(npm view @wireapp/commons dist-tags.latest) \ | |
| @wireapp/core@$(npm view @wireapp/core dist-tags.latest) \ | |
| @wireapp/promise-queue@$(npm view @wireapp/promise-queue dist-tags.latest) \ | |
| @wireapp/react-ui-kit@$(npm view @wireapp/react-ui-kit dist-tags.latest) \ | |
| @wireapp/store-engine-dexie@$(npm view @wireapp/store-engine-dexie dist-tags.latest) \ | |
| @wireapp/telemetry@$(npm view @wireapp/telemetry dist-tags.latest) \ | |
| @wireapp/webapp-events@$(npm view @wireapp/webapp-events dist-tags.latest) \ | |
| @wireapp/copy-config@$(npm view @wireapp/copy-config dist-tags.latest) \ | |
| @wireapp/eslint-config@$(npm view @wireapp/eslint-config dist-tags.latest) \ | |
| @wireapp/prettier-config@$(npm view @wireapp/prettier-config dist-tags.latest) | |
| # Fetch all versions first to fail fast if registry is unreachable or a package is missing | |
| STORE_ENGINE=$(npm view @wireapp/store-engine dist-tags.latest) || { echo "Failed to fetch @wireapp/store-engine version" >&2; exit 1; } | |
| COMMONS=$(npm view @wireapp/commons dist-tags.latest) || { echo "Failed to fetch @wireapp/commons version" >&2; exit 1; } | |
| CORE=$(npm view @wireapp/core dist-tags.latest) || { echo "Failed to fetch @wireapp/core version" >&2; exit 1; } | |
| PROMISE_QUEUE=$(npm view @wireapp/promise-queue dist-tags.latest) || { echo "Failed to fetch @wireapp/promise-queue version" >&2; exit 1; } | |
| REACT_UI_KIT=$(npm view @wireapp/react-ui-kit dist-tags.latest) || { echo "Failed to fetch @wireapp/react-ui-kit version" >&2; exit 1; } | |
| STORE_ENGINE_DEXIE=$(npm view @wireapp/store-engine-dexie dist-tags.latest) || { echo "Failed to fetch @wireapp/store-engine-dexie version" >&2; exit 1; } | |
| TELEMETRY=$(npm view @wireapp/telemetry dist-tags.latest) || { echo "Failed to fetch @wireapp/telemetry version" >&2; exit 1; } | |
| WEBAPP_EVENTS=$(npm view @wireapp/webapp-events dist-tags.latest) || { echo "Failed to fetch @wireapp/webapp-events version" >&2; exit 1; } | |
| COPY_CONFIG=$(npm view @wireapp/copy-config dist-tags.latest) || { echo "Failed to fetch @wireapp/copy-config version" >&2; exit 1; } | |
| ESLINT_CONFIG=$(npm view @wireapp/eslint-config dist-tags.latest) || { echo "Failed to fetch @wireapp/eslint-config version" >&2; exit 1; } | |
| PRETTIER_CONFIG=$(npm view @wireapp/prettier-config dist-tags.latest) || { echo "Failed to fetch @wireapp/prettier-config version" >&2; exit 1; } | |
| yarn add \ | |
| @wireapp/store-engine@${STORE_ENGINE} \ | |
| @wireapp/commons@${COMMONS} \ | |
| @wireapp/core@${CORE} \ | |
| @wireapp/promise-queue@${PROMISE_QUEUE} \ | |
| @wireapp/react-ui-kit@${REACT_UI_KIT} \ | |
| @wireapp/store-engine-dexie@${STORE_ENGINE_DEXIE} \ | |
| @wireapp/telemetry@${TELEMETRY} \ | |
| @wireapp/webapp-events@${WEBAPP_EVENTS} \ | |
| @wireapp/copy-config@${COPY_CONFIG} \ | |
| @wireapp/eslint-config@${ESLINT_CONFIG} \ | |
| @wireapp/prettier-config@${PRETTIER_CONFIG} |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Blocker] The dependency update list is incomplete. Based on package.json, the following @wireapp packages are missing from this update:
@wireapp/avs(dependency)@wireapp/avs-debugger(dependency)@wireapp/kalium-backup(dependency)
These packages should either be included in the update or explicitly documented why they're excluded. If they follow a different versioning strategy, that should be noted in a comment.
| @wireapp/store-engine@$(npm view @wireapp/store-engine dist-tags.latest) \ | |
| @wireapp/commons@$(npm view @wireapp/commons dist-tags.latest) \ | |
| @wireapp/core@$(npm view @wireapp/core dist-tags.latest) \ | |
| @wireapp/promise-queue@$(npm view @wireapp/promise-queue dist-tags.latest) \ | |
| @wireapp/react-ui-kit@$(npm view @wireapp/react-ui-kit dist-tags.latest) \ | |
| @wireapp/store-engine-dexie@$(npm view @wireapp/store-engine-dexie dist-tags.latest) \ | |
| @wireapp/telemetry@$(npm view @wireapp/telemetry dist-tags.latest) \ | |
| @wireapp/webapp-events@$(npm view @wireapp/webapp-events dist-tags.latest) \ | |
| @wireapp/copy-config@$(npm view @wireapp/copy-config dist-tags.latest) \ | |
| @wireapp/eslint-config@$(npm view @wireapp/eslint-config dist-tags.latest) \ | |
| @wireapp/prettier-config@$(npm view @wireapp/prettier-config dist-tags.latest) | |
| @wireapp/avs@$(npm view @wireapp/avs dist-tags.latest) \ | |
| @wireapp/avs-debugger@$(npm view @wireapp/avs-debugger dist-tags.latest) \ | |
| @wireapp/commons@$(npm view @wireapp/commons dist-tags.latest) \ | |
| @wireapp/copy-config@$(npm view @wireapp/copy-config dist-tags.latest) \ | |
| @wireapp/core@$(npm view @wireapp/core dist-tags.latest) \ | |
| @wireapp/eslint-config@$(npm view @wireapp/eslint-config dist-tags.latest) \ | |
| @wireapp/kalium-backup@$(npm view @wireapp/kalium-backup dist-tags.latest) \ | |
| @wireapp/prettier-config@$(npm view @wireapp/prettier-config dist-tags.latest) \ | |
| @wireapp/promise-queue@$(npm view @wireapp/promise-queue dist-tags.latest) \ | |
| @wireapp/react-ui-kit@$(npm view @wireapp/react-ui-kit dist-tags.latest) \ | |
| @wireapp/store-engine@$(npm view @wireapp/store-engine dist-tags.latest) \ | |
| @wireapp/store-engine-dexie@$(npm view @wireapp/store-engine-dexie dist-tags.latest) \ | |
| @wireapp/telemetry@$(npm view @wireapp/telemetry dist-tags.latest) \ | |
| @wireapp/webapp-events@$(npm view @wireapp/webapp-events dist-tags.latest) |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] [Suggestion] The Show diff step is helpful for debugging but doesn't fail the workflow if there are no changes. Consider adding a check to ensure dependencies were actually updated:
- name: Show diff and verify changes
run: |
git diff
if ! git diff --quiet; then
echo "✓ Dependencies updated successfully"
else
echo "⚠️ Warning: No changes detected after dependency update" >&2
fiThis helps catch scenarios where all packages are already at the latest version.
| - name: Show diff | |
| run: git diff | |
| - name: Show diff and verify changes | |
| run: | | |
| git diff | |
| if git diff --quiet; then | |
| echo "⚠️ Warning: No changes detected after dependency update" >&2 | |
| else | |
| echo "✓ Dependencies updated successfully" | |
| fi |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Important] Using GITHUB_TOKEN for automated PR creation is inconsistent with other workflows in this repository. All other automated PR workflows (cherry-pick, translations sync) use OTTO_THE_BOT_GH_TOKEN, which:
- Properly attributes the PR to the bot user
- Allows triggered workflows to run (GITHUB_TOKEN-created PRs don't trigger workflows by design)
- Maintains consistency across the repository
Change to:
token: ${{ secrets.OTTO_THE_BOT_GH_TOKEN }}| token: ${{ secrets.GITHUB_TOKEN }} | |
| token: ${{ secrets.OTTO_THE_BOT_GH_TOKEN }} |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Suggestion] The commit message and PR title use the full RC branch name which may not be descriptive. Consider a more informative format:
commit-message: 'chore: Prepare release candidate ${{ inputs.rc_branch }}'And for the title (line 68):
title: 'chore: Prepare release candidate ${{ inputs.rc_branch }}'This makes it clearer that this is an RC preparation PR when reviewing the commit history.
| commit-message: 'chore: ${{ inputs.rc_branch }}' | |
| branch: ${{ inputs.rc_branch }} | |
| base: master | |
| title: 'chore: ${{ inputs.rc_branch }}' | |
| commit-message: 'chore: Prepare release candidate ${{ inputs.rc_branch }}' | |
| branch: ${{ inputs.rc_branch }} | |
| base: master | |
| title: 'chore: Prepare release candidate ${{ inputs.rc_branch }}' |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Important] sign-commits: true may not work correctly with GITHUB_TOKEN. According to peter-evans/create-pull-request documentation, signed commits require either:
- A Personal Access Token (PAT) with signing configured
- The bot token to have GPG signing set up
Since line 64 uses GITHUB_TOKEN (which should be changed to OTTO_THE_BOT_GH_TOKEN per another comment), ensure that otto-the-bot has GPG signing configured. If not, remove this line or configure signing for the bot account.
| sign-commits: true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,10 +13,10 @@ | |
| "@mediapipe/tasks-vision": "0.10.21", | ||
| "@tanstack/react-table": "8.21.3", | ||
| "@tanstack/react-virtual": "3.13.4", | ||
| "@wireapp/avs": "10.2.17", | ||
| "@wireapp/avs": "10.2.19", | ||
| "@wireapp/avs-debugger": "0.0.7", | ||
| "@wireapp/commons": "5.4.9", | ||
| "@wireapp/core": "46.46.3", | ||
| "@wireapp/core": "46.46.5", | ||
| "@wireapp/kalium-backup": "0.0.4", | ||
| "@wireapp/promise-queue": "2.4.9", | ||
| "@wireapp/react-ui-kit": "9.69.6", | ||
|
|
@@ -27,11 +27,11 @@ | |
| "beautiful-react-hooks": "5.0.3", | ||
| "classnames": "2.5.1", | ||
| "copy-webpack-plugin": "13.0.1", | ||
| "core-js": "3.46.0", | ||
| "core-js": "3.47.0", | ||
| "date-fns": "4.1.0", | ||
| "dexie-batch": "0.4.3", | ||
| "dexie-encrypted": "2.0.0", | ||
| "emoji-picker-react": "4.15.1", | ||
| "emoji-picker-react": "4.15.2", | ||
| "http-status-codes": "2.3.0", | ||
| "immer": "10.2.0", | ||
| "jimp": "0.22.12", | ||
|
|
@@ -45,7 +45,7 @@ | |
| "long": "5.3.2", | ||
| "markdown-it": "14.0.0", | ||
| "murmurhash": "2.0.1", | ||
| "oidc-client-ts": "3.4.0", | ||
| "oidc-client-ts": "3.4.1", | ||
| "path-to-regexp": "8.3.0", | ||
| "platform": "1.3.6", | ||
| "prism-themes": "^1.9.0", | ||
|
|
@@ -123,7 +123,7 @@ | |
| "autoprefixer": "10.4.22", | ||
| "babel-loader": "10.0.0", | ||
| "babel-plugin-transform-import-meta": "2.3.3", | ||
| "baseline-browser-mapping": "^2.8.28", | ||
| "baseline-browser-mapping": "^2.8.31", | ||
| "browserslist": "^4.28.0", | ||
| "cross-env": "7.0.3", | ||
| "css-loader": "7.1.2", | ||
|
|
@@ -135,7 +135,7 @@ | |
| "eslint-plugin-prettier": "5.1.3", | ||
| "fake-indexeddb": "6.2.5", | ||
| "generate-changelog": "1.8.0", | ||
| "html-webpack-plugin": "5.6.4", | ||
| "html-webpack-plugin": "5.6.5", | ||
| "husky": "9.1.7", | ||
| "i18next-scanner": "4.6.0", | ||
| "intersection-observer": "0.12.2", | ||
|
|
@@ -164,19 +164,19 @@ | |
| "simple-git": "3.30.0", | ||
| "sinon": "18.0.0", | ||
| "style-loader": "4.0.0", | ||
| "stylelint": "16.25.0", | ||
| "stylelint": "16.26.0", | ||
| "stylelint-config-idiomatic-order": "10.0.0", | ||
| "svg-inline-loader": "0.8.2", | ||
| "text-encoding": "0.7.0", | ||
| "ts-node": "10.9.2", | ||
| "tsc-watch": "6.2.1", | ||
| "typescript": "5.5.2", | ||
| "webpack": "5.102.1", | ||
| "webpack": "5.103.0", | ||
| "webpack-bundle-analyzer": "^4.10.2", | ||
| "webpack-cli": "6.0.1", | ||
| "webpack-dev-middleware": "7.4.5", | ||
| "webpack-hot-middleware": "2.26.1", | ||
| "workbox-webpack-plugin": "7.3.0" | ||
| "workbox-webpack-plugin": "7.4.0" | ||
| }, | ||
| "engines": { | ||
| "yarn": ">= 4.1.1", | ||
|
|
@@ -237,7 +237,8 @@ | |
| "xml2js": "0.5.0", | ||
| "@stablelib/utf8": "1.0.2", | ||
| "[email protected]": "patch:dexie-encrypted@npm%3A2.0.0#./.yarn/patches/dexie-encrypted-npm-2.0.0-eb61eb5975.patch", | ||
| "axios": "^1.9.0" | ||
| "axios": "^1.9.0", | ||
| "js-yaml": "^4.1.0" | ||
| }, | ||
| "version": "0.27.0", | ||
| "packageManager": "[email protected]" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| /* | ||
| * Wire | ||
| * Copyright (C) 2025 Wire Swiss GmbH | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see http://www.gnu.org/licenses/. | ||
| * | ||
| */ | ||
|
|
||
| import {useRouteA11y} from '../hooks/useRouteA11y'; | ||
|
|
||
| export const RouteA11y: React.FC = (): null => { | ||
| useRouteA11y(); | ||
| return null; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| /* | ||
| * Wire | ||
| * Copyright (C) 2025 Wire Swiss GmbH | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see http://www.gnu.org/licenses/. | ||
| * | ||
| */ | ||
|
|
||
| import {useEffect} from 'react'; | ||
|
|
||
| import {useLocation} from 'react-router-dom'; | ||
|
|
||
| export function useRouteA11y(screenKey?: string) { | ||
| const location = useLocation(); | ||
|
|
||
| useEffect(() => { | ||
| const focusTarget: HTMLElement | null = | ||
| document.querySelector<HTMLElement>('[data-page-title]') || | ||
| document.querySelector<HTMLElement>('main,[role="main"]') || | ||
| document.querySelector<HTMLElement>('h1'); | ||
|
|
||
| if (!focusTarget) { | ||
| return; | ||
| } | ||
|
|
||
| // scroll to top on each route change | ||
| window.scrollTo({top: 0, left: 0}); | ||
|
|
||
| const element = focusTarget; | ||
| element.setAttribute('tabindex', '-1'); | ||
| element.classList.add('sr-only-focus'); | ||
| element.focus({preventScroll: true}); | ||
|
|
||
| // remove tabindex after blur | ||
| const handleBlur = () => { | ||
| element.classList.remove('sr-only-focus'); | ||
| element.removeAttribute('tabindex'); | ||
| element.removeEventListener('blur', handleBlur); | ||
| }; | ||
| element.addEventListener('blur', handleBlur); | ||
| }, [location.key, screenKey]); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Important] The
rc_branchinput lacks validation and could be exploited for command injection or create unintended branch names. Although GitHub Actions provides some sanitization, it's best practice to explicitly validate the input format.Consider adding a validation step after checkout: