Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d77bb74
Enforce repository branch name rules in Rename Branch dialog
tidy-dev Mar 18, 2026
5f1829d
Add componentWillUnmount to clear debounce timer
tidy-dev Mar 18, 2026
0ec4a05
Fix rename branch dialog width to prevent jarring resize
tidy-dev Mar 18, 2026
cf3e05a
Validate branch name against repo rules on dialog open
tidy-dev Mar 18, 2026
e5252d9
Add E2E tests for critical paths
sergiou87 Mar 19, 2026
6a256fa
Update yarn.lock
sergiou87 Mar 19, 2026
fb50414
E2E: support unpackaged mode and skip packaging
sergiou87 Mar 19, 2026
2d2a69e
Upload E2E artifacts in CI
sergiou87 Mar 19, 2026
2655bf9
Extract CI setup into reusable actions
sergiou87 Mar 19, 2026
7dfa5c4
Add E2E smoke tests docs; remove Playwright script
sergiou87 Mar 19, 2026
f3b3ff0
Extract shared branch name rule validation
tidy-dev Mar 19, 2026
7e8219d
Update globals.mts
sergiou87 Mar 19, 2026
f08f0c5
Cleanup
sergiou87 Mar 19, 2026
d3ebe21
Improve types
sergiou87 Mar 19, 2026
a66348c
Guard macOS-only dialog in e2e fixtures
sergiou87 Mar 19, 2026
f037d09
Delete default-to-tls12-on-appveyor.reg
sergiou87 Mar 20, 2026
deb80c8
Add test setup step to CI workflow
sergiou87 Mar 20, 2026
e62514c
Update app/test/e2e/app-launch.e2e.ts
sergiou87 Mar 20, 2026
e51ee81
Update app/test/e2e/mock-update-server.ts
sergiou87 Mar 20, 2026
a83f116
Update app/test/e2e/e2e-fixtures.ts
sergiou87 Mar 20, 2026
c271865
Run Windows signing action only on Windows runners
sergiou87 Mar 20, 2026
6b74e82
Grant id-token write permission in CI workflow
sergiou87 Mar 20, 2026
b8db939
Refactor E2E auto-update checks
sergiou87 Mar 20, 2026
5de669d
Use expect.poll for update status in e2e test
sergiou87 Mar 20, 2026
88f886d
Merge pull request #21823 from desktop/add-e2e-tests-critical-paths
sergiou87 Mar 23, 2026
6048b64
Merge pull request #21822 from desktop/rename-branch-repo-rules
tidy-dev Mar 23, 2026
e496d70
Merge branch 'upstream-development'
pol-rivero Mar 24, 2026
9f0982f
Fix e2e tests
pol-rivero Mar 24, 2026
c2f47e1
Update docker test environment to match CI
pol-rivero Mar 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/actions/setup-ci-environment/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Setup CI Environment
description: Set up Python, Node.js, optional ffmpeg, and install dependencies.

inputs:
node-version:
description: Node.js version to use.
required: true
arch:
description: Target architecture for dependency installation.
required: true
install-ffmpeg:
description: Whether to install ffmpeg on Windows.
required: false
default: 'false'

runs:
using: composite
steps:
- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Use Node.js ${{ inputs.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: yarn

- name: Install ffmpeg
if: ${{ runner.os == 'Windows' && inputs.install-ffmpeg == 'true' }}
shell: bash
run: choco install ffmpeg --yes --no-progress

- name: Install and build dependencies
shell: bash
run: yarn
env:
npm_config_arch: ${{ inputs.arch }}
TARGET_ARCH: ${{ inputs.arch }}
35 changes: 35 additions & 0 deletions .github/actions/setup-windows-signing/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Setup Windows Signing
description: Install Azure Code Signing prerequisites and authenticate.

inputs:
enabled:
description: Whether Windows signing setup should run.
required: false
default: 'false'
azure-client-id:
description: Azure Code Signing client ID.
required: false
azure-tenant-id:
description: Azure Code Signing tenant ID.
required: false

runs:
using: composite
steps:
- name: Install Azure Code Signing Client
if: ${{ runner.os == 'Windows' && inputs.enabled == 'true' }}
shell: pwsh
run: |
$acsZip = Join-Path $env:RUNNER_TEMP "acs.zip"
$acsDir = Join-Path $env:RUNNER_TEMP "acs"
Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.Trusted.Signing.Client/1.0.95 -OutFile $acsZip -Verbose
Expand-Archive $acsZip -Destination $acsDir -Force -Verbose
Copy-Item -Path "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\*" -Include signtool.exe,signtool.exe.manifest,Microsoft.Windows.Build.Signing.mssign32.dll.manifest,mssign32.dll,Microsoft.Windows.Build.Signing.wintrust.dll.manifest,wintrust.dll,Microsoft.Windows.Build.Appx.AppxSip.dll.manifest,AppxSip.dll,Microsoft.Windows.Build.Appx.AppxPackaging.dll.manifest,AppxPackaging.dll,Microsoft.Windows.Build.Appx.OpcServices.dll.manifest,OpcServices.dll -Destination "node_modules\electron-winstaller\vendor" -Verbose

- name: Azure Login (OIDC)
if: ${{ runner.os == 'Windows' && inputs.enabled == 'true' }}
uses: azure/login@v2
with:
client-id: ${{ inputs.azure-client-id }}
tenant-id: ${{ inputs.azure-tenant-id }}
allow-no-subscriptions: true
164 changes: 138 additions & 26 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,10 @@ jobs:
repository: ${{ inputs.repository || github.repository }}
ref: ${{ inputs.ref }}
submodules: recursive
- uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Use Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v6
- uses: ./.github/actions/setup-ci-environment
with:
node-version: ${{ env.NODE_VERSION }}
cache: yarn
- name: Install and build dependencies
run: yarn
env:
npm_config_arch: ${{ matrix.arch }}
TARGET_ARCH: ${{ matrix.arch }}
arch: ${{ matrix.arch }}
- name: Validate macOS version
if: runner.os == 'macOS'
run: yarn validate-macos-version
Expand Down Expand Up @@ -189,22 +180,12 @@ jobs:
run: yarn test:unit
- name: Run script tests
run: yarn test:script
- name: Install Azure Code Signing Client
if: ${{ runner.os == 'Windows' }}
run: |
$acsZip = Join-Path $env:RUNNER_TEMP "acs.zip"
$acsDir = Join-Path $env:RUNNER_TEMP "acs"
Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.Trusted.Signing.Client/1.0.95 -OutFile $acsZip -Verbose
Expand-Archive $acsZip -Destination $acsDir -Force -Verbose
# Replace ancient signtool in electron-winstall with one that supports ACS
Copy-Item -Path "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\*" -Include signtool.exe,signtool.exe.manifest,Microsoft.Windows.Build.Signing.mssign32.dll.manifest,mssign32.dll,Microsoft.Windows.Build.Signing.wintrust.dll.manifest,wintrust.dll,Microsoft.Windows.Build.Appx.AppxSip.dll.manifest,AppxSip.dll,Microsoft.Windows.Build.Appx.AppxPackaging.dll.manifest,AppxPackaging.dll,Microsoft.Windows.Build.Appx.OpcServices.dll.manifest,OpcServices.dll -Destination "node_modules\electron-winstaller\vendor" -Verbose
- name: Azure Login (OIDC)
if: ${{ runner.os == 'Windows' && inputs.sign }}
uses: azure/login@v2
- if: runner.os == 'Windows'
uses: ./.github/actions/setup-windows-signing
with:
client-id: ${{ secrets.AZURE_CODE_SIGNING_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_CODE_SIGNING_TENANT_ID }}
allow-no-subscriptions: true
enabled: ${{ inputs.sign }}
azure-client-id: ${{ secrets.AZURE_CODE_SIGNING_CLIENT_ID }}
azure-tenant-id: ${{ secrets.AZURE_CODE_SIGNING_TENANT_ID }}
- name: Package production app
run: yarn package
env:
Expand Down Expand Up @@ -233,6 +214,137 @@ jobs:
dist/bundle-size.json
if-no-files-found: error

e2e-smoke:
name: E2E Smoke ${{ matrix.friendlyName }} ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
permissions:
contents: read
id-token: write
strategy:
fail-fast: false
matrix:
include:
- os: macos-14
friendlyName: macOS
arch: arm64
- os: windows-2022
friendlyName: Windows
arch: x64
timeout-minutes: 60
environment: ${{ inputs.environment }}
env:
RELEASE_CHANNEL: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v4
with:
repository: ${{ inputs.repository || github.repository }}
ref: ${{ inputs.ref }}
submodules: recursive
- uses: ./.github/actions/setup-ci-environment
with:
node-version: ${{ env.NODE_VERSION }}
arch: ${{ matrix.arch }}
install-ffmpeg: 'true'
- name: Build production app
run: yarn build:prod
env:
DESKTOP_E2E_UPDATES_URL: http://127.0.0.1:51789/update
DESKTOP_OAUTH_CLIENT_ID: ${{ secrets.DESKTOP_OAUTH_CLIENT_ID }}
DESKTOP_OAUTH_CLIENT_SECRET:
${{ secrets.DESKTOP_OAUTH_CLIENT_SECRET }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_APPLICATION_CERT: ${{ secrets.APPLE_APPLICATION_CERT }}
KEY_PASSWORD: ${{ secrets.APPLE_APPLICATION_CERT_PASSWORD }}
npm_config_arch: ${{ matrix.arch }}
TARGET_ARCH: ${{ matrix.arch }}
- name: Prepare testing environment
run: yarn test:setup
env:
npm_config_arch: ${{ matrix.arch }}
- if: runner.os == 'Windows'
uses: ./.github/actions/setup-windows-signing
with:
enabled: ${{ inputs.sign }}
azure-client-id: ${{ secrets.AZURE_CODE_SIGNING_CLIENT_ID }}
azure-tenant-id: ${{ secrets.AZURE_CODE_SIGNING_TENANT_ID }}
- name: Package production app
run: yarn package
env:
npm_config_arch: ${{ matrix.arch }}
AZURE_TENANT_ID: ${{ secrets.AZURE_CODE_SIGNING_TENANT_ID }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CODE_SIGNING_CLIENT_ID }}
- name: Install app on macOS
if: runner.os == 'macOS'
run: |
rm -rf "/Applications/GitHub Desktop Plus.app"
ditto "dist/GitHub Desktop Plus-darwin-arm64/GitHub Desktop Plus.app" "/Applications/GitHub Desktop Plus.app"
echo "DESKTOP_E2E_APP_PATH=/Applications/GitHub Desktop Plus.app/Contents/MacOS/GitHub Desktop Plus" >> "$GITHUB_ENV"
- name: Install app on Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
function Write-SquirrelLogs {
$logPaths = @(
"$env:LOCALAPPDATA\SquirrelSetup.log",
"$env:LOCALAPPDATA\GitHubDesktopPlus\SquirrelSetup.log"
)

foreach ($logPath in $logPaths) {
if (Test-Path $logPath) {
Write-Host "Showing log: $logPath"
Get-Content $logPath -Tail 200
}
}
}

$setupExe = Get-ChildItem "dist/GitHubDesktopPlus-*-windows-${{ matrix.arch }}.exe" -ErrorAction SilentlyContinue |
Sort-Object FullName -Descending |
Select-Object -First 1 -ExpandProperty FullName

if (-not $setupExe) {
throw "Unable to locate Windows installer executable"
}

$installer = Start-Process -FilePath $setupExe -ArgumentList "/S" -PassThru

try {
Wait-Process -Id $installer.Id -Timeout 300 -ErrorAction Stop
} catch {
Write-SquirrelLogs
throw "Windows installer timed out after 300 seconds"
}

Get-Process GitHubDesktopPlus -ErrorAction SilentlyContinue | Stop-Process -Force

$installedExe = $null
for ($attempt = 0; $attempt -lt 30 -and -not $installedExe; $attempt++) {
$installedExe = Get-ChildItem "$env:LOCALAPPDATA\GitHubDesktopPlus\app-*\GitHubDesktopPlus.exe" -ErrorAction SilentlyContinue |
Sort-Object FullName -Descending |
Select-Object -First 1 -ExpandProperty FullName

if (-not $installedExe) {
Start-Sleep -Seconds 2
}
}

if (-not $installedExe) {
Write-SquirrelLogs
throw "Unable to locate installed GitHub Desktop executable"
}

Add-Content -Path $env:GITHUB_ENV -Value "DESKTOP_E2E_APP_PATH=$installedExe"
- name: Run packaged E2E smoke tests
run: yarn test:e2e:run:packaged
- name: Upload E2E artifacts
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: e2e-${{matrix.friendlyName}}-${{matrix.arch}}
path: playwright-videos/**
if-no-files-found: warn

release_github:
name: Create GitHub release
needs: [build, compute_version]
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ junit*.xml
*.swp
tslint-rules/
script/release_notes.txt
playwright-videos/
2 changes: 1 addition & 1 deletion app/app-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function getReplacements() {
__DEV__: isDevBuild,
__DEV_SECRETS__: isDevBuild || !process.env.DESKTOP_OAUTH_CLIENT_SECRET,
__RELEASE_CHANNEL__: s(channel),
__UPDATES_URL__: s(getUpdatesURL()),
__UPDATES_URL__: s(process.env.DESKTOP_E2E_UPDATES_URL ?? getUpdatesURL()),
__SHA__: s(getSHA()),
'process.platform': s(process.platform),
'process.env.NODE_ENV': s(process.env.NODE_ENV || 'development'),
Expand Down
2 changes: 2 additions & 0 deletions app/src/ui/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,8 @@ export class App extends React.Component<IAppProps, IAppState> {
dispatcher={this.props.dispatcher}
repository={popup.repository}
branch={popup.branch}
accounts={this.state.accounts}
cachedRepoRulesets={this.state.cachedRepoRulesets}
onDismissed={onPopupDismissedFn}
/>
)
Expand Down
2 changes: 1 addition & 1 deletion app/src/ui/branches/branch-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ export class BranchList extends React.Component<IBranchListProps> {

private onRenderNewButton = () => {
return this.props.canCreateNewBranch ? (
<Button onClick={this.onCreateNewBranch}>
<Button className="new-branch-button" onClick={this.onCreateNewBranch}>
<Octicon symbol={octicons.plus} className="mr" />
{__DARWIN__ ? 'New Branch' : 'New branch'}
</Button>
Expand Down
Loading
Loading