diff --git a/.agents/skills/changelog-to-jira/README.md b/.agents/skills/changelog-to-jira/README.md index 8839c7fb7..e77a7cb0c 100644 --- a/.agents/skills/changelog-to-jira/README.md +++ b/.agents/skills/changelog-to-jira/README.md @@ -18,14 +18,8 @@ Install-Module JiraPS -Scope CurrentUser ### Atlassian API token -Generate one at . - -The token must have the following Jira scopes: - -| Scope | Why | -|---|---| -| `read:jira-work` | Read issues and transitions | -| `write:jira-work` | Create issues, add links, perform transitions | +Generate one at with **Create API token**, not **Create API token with scopes**. +The script calls `JIRA_URL` directly, and Jira rejects scoped tokens there with `Client must be authenticated to access this resource.` ### Environment variables diff --git a/.agents/skills/changelog-to-jira/SKILL.md b/.agents/skills/changelog-to-jira/SKILL.md index 8095ffc95..70c3d8071 100644 --- a/.agents/skills/changelog-to-jira/SKILL.md +++ b/.agents/skills/changelog-to-jira/SKILL.md @@ -193,6 +193,7 @@ pwsh /scripts/invoke-jira.ps1 -PlanFile jira-plan.json ``` The script handles everything mechanical: creating each ticket, linking cross-project tickets, walking the DGW workflow to Done (`Backlog → To Do → Development → Reviewing → Done`), and deleting `jira-plan.json` when done. +If a ticket is created but can't be moved to Done, the script warns with the transitions Jira offers and keeps going; report it so the user can move the ticket manually. The result JSON is written to stdout: diff --git a/.agents/skills/changelog-to-jira/scripts/invoke-jira.ps1 b/.agents/skills/changelog-to-jira/scripts/invoke-jira.ps1 index 3751260ed..0e0e649af 100644 --- a/.agents/skills/changelog-to-jira/scripts/invoke-jira.ps1 +++ b/.agents/skills/changelog-to-jira/scripts/invoke-jira.ps1 @@ -61,14 +61,43 @@ New-JiraSession -Credential $Credential | Out-Null Write-Verbose "Connected to $JiraUrl as $JiraEmail" # --------------------------------------------------------------------------- -# 3. DGW workflow transition chain -# Backlog(961) → To Do(861) → Development(731) → Reviewing(741) → Done -# These IDs are stable for the DGW project. If a transition fails, -# fetch the current transitions with Get-JiraIssueTransition and update -# this list. +# 3. DGW workflow +# Backlog → To Do → Development → Reviewing → Done +# Transitions are picked by the status they lead to, because their IDs +# change whenever the workflow is edited. If the statuses change, the +# error lists the transitions Jira offers; update this list from it. # --------------------------------------------------------------------------- -$TransitionChain = @(961, 861, 731, 741) +$StatusChain = @("Backlog", "To Do", "Development", "Reviewing", "Done") + +function Move-JiraIssueToDone { + param([Parameter(Mandatory)] [string] $Key) + + # Each transition moves the issue at least one status forward, so this needs at most one step per status. + for ($step = 0; $step -lt $StatusChain.Count; $step++) { + $current = Get-JiraIssue -Key $Key + $position = [array]::IndexOf($StatusChain, $current.Status) + + if ($position -eq $StatusChain.Count - 1) { + return + } + + # Take the transition that goes furthest along the chain, straight to Done when the workflow allows it. + $next = $current.Transition | + Where-Object { [array]::IndexOf($StatusChain, $_.ResultStatus.Name) -gt $position } | + Sort-Object { [array]::IndexOf($StatusChain, $_.ResultStatus.Name) } -Descending | + Select-Object -First 1 + + if (-not $next) { + $available = ($current.Transition | ForEach-Object { "$($_.Name) ($($_.ID)) → $($_.ResultStatus.Name)" }) -join ", " + throw "no transition moves $Key forward from '$($current.Status)'; available: $available" + } + + Invoke-JiraIssueTransition -Issue $Key -Transition $next + } + + throw "$Key did not reach '$($StatusChain[-1])' after $($StatusChain.Count) transitions" +} # --------------------------------------------------------------------------- # 4. Process tickets @@ -91,7 +120,8 @@ foreach ($ticket in $plan.tickets) { Description = $ticket.description } if ($ticket.assignee_account_id) { - $issueParams["Assignee"] = $ticket.assignee_account_id + # New-JiraIssue has no -Assignee parameter; -Fields entries go straight into the request body. + $issueParams["Fields"] = @{ assignee = @{ accountId = $ticket.assignee_account_id } } } $issue = New-JiraIssue @issueParams @@ -109,22 +139,13 @@ foreach ($ticket in $plan.tickets) { } } - # --- Walk through transition chain to Done --- - $allTransitionsSucceeded = $true - foreach ($transId in $TransitionChain) { - try { - Invoke-JiraIssueTransition -Issue $issue.Key -Transition $transId - } catch { - Write-Warning " Transition $transId failed for $($issue.Key): $_" - Write-Warning " Remaining transitions skipped — ticket may need manual progression." - $allTransitionsSucceeded = $false - break - } - } - if ($allTransitionsSucceeded) { + # --- Walk the workflow to Done --- + try { + Move-JiraIssueToDone -Key $issue.Key Write-Host " Transitioned $($issue.Key) to Done" - } else { - Write-Host " Did not fully transition $($issue.Key) to Done" + } catch { + Write-Warning " Could not move $($issue.Key) to Done: $_" + Write-Warning " The ticket needs to be moved to Done manually." } $created.Add(@{ id = $ticket.id; key = $issue.Key }) diff --git a/CHANGELOG.md b/CHANGELOG.md index 681d345aa..ea75a9753 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ This document provides a list of notable changes introduced in Devolutions Gateway service, installer and Jetsocat. +## 2026.3.3 (2026-10-14) + +### Features + +- _dgw_: keep agent tunnel data in a shared gateway.db ([#2039](https://github.com/Devolutions/devolutions-gateway/issues/2039)) ([e8ac5ef235](https://github.com/Devolutions/devolutions-gateway/commit/e8ac5ef235cea5f748043ae49baf636cd4bd2e62)) ([DGW-464](https://devolutions.atlassian.net/browse/DGW-464)) + + Agent Tunnel data moves from `agent_tunnel.db` to `gateway.db` in the Gateway data directory. + Gateway creates `gateway.db` on every start, even when Agent Tunnel is disabled. + On the first start after upgrading, Gateway imports and removes an existing `agent_tunnel.db`, so enrolled agents keep working without enrolling again. + Downgrading afterwards means agents have to enroll again, because earlier versions only read `agent_tunnel.db`. + +- _dgw_: honor an explicit agent on KDC tokens ([#2068](https://github.com/Devolutions/devolutions-gateway/issues/2068)) ([458a0db6e4](https://github.com/Devolutions/devolutions-gateway/commit/458a0db6e4b8ac945ce75d3176089aa30846208b)) ([DGW-453](https://devolutions.atlassian.net/browse/DGW-453)) + + KDC tokens can name an explicit agent with `jet_agent_id`, as association and JMUX tokens already do. + `/jet/KdcProxy` then sends every Kerberos message through that agent or fails, without falling back to a direct connection or another agent; tokens without the claim keep working as before. + Previously, the client's Kerberos traffic for an RDP session pinned to an agent could reach the KDC directly from Gateway or through a different agent. + Through an agent, the KDC must use `tcp://`: a `udp://` KDC with an explicit agent is rejected. + +### Bug Fixes + +- _dgw,agent_: fix Windows service crash at startup ([#2069](https://github.com/Devolutions/devolutions-gateway/issues/2069)) ([20c0119493](https://github.com/Devolutions/devolutions-gateway/commit/20c011949311b87c3422656e4472291b409ee9a1)) ([DGW-460](https://devolutions.atlassian.net/browse/DGW-460)) + + The Gateway Windows service could crash at startup with an access violation in `ntdll.dll` and never start, as seen after updating to 2026.3.2 on Windows Server 2016. + The Agent Windows service could crash the same way and is fixed too. + When the service fails to start, for example because of an invalid configuration, Gateway and Agent now exit with a nonzero status, so service managers such as systemd can detect the failure and restart them. + ## 2026.3.2 (2026-10-09) ### Bug Fixes diff --git a/Cargo.lock b/Cargo.lock index e64afe888..0f5bac1cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1740,7 +1740,7 @@ dependencies = [ [[package]] name = "devolutions-agent" -version = "2026.3.2" +version = "2026.3.3" dependencies = [ "agent-tunnel-proto", "anyhow", @@ -1820,7 +1820,7 @@ dependencies = [ [[package]] name = "devolutions-agent-updater" -version = "2026.3.2" +version = "2026.3.3" dependencies = [ "anyhow", "win-api-wrappers", @@ -1828,7 +1828,7 @@ dependencies = [ [[package]] name = "devolutions-gateway" -version = "2026.3.2" +version = "2026.3.3" dependencies = [ "agent-tunnel", "agent-tunnel-libsql", @@ -1981,7 +1981,7 @@ dependencies = [ [[package]] name = "devolutions-pedm" -version = "2026.3.2" +version = "2026.3.3" dependencies = [ "aide 0.14.2", "anyhow", @@ -2069,7 +2069,7 @@ dependencies = [ [[package]] name = "devolutions-pedm-shell-ext" -version = "2026.3.2" +version = "2026.3.3" dependencies = [ "devolutions-pedm-shared", "embed-resource", @@ -2082,7 +2082,7 @@ dependencies = [ [[package]] name = "devolutions-session" -version = "2026.3.2" +version = "2026.3.3" dependencies = [ "anyhow", "async-trait", @@ -3835,7 +3835,7 @@ dependencies = [ [[package]] name = "jetsocat" -version = "2026.3.2" +version = "2026.3.3" dependencies = [ "anyhow", "base64 0.23.1", diff --git a/Cargo.toml b/Cargo.toml index f7ea0a98c..374d997fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ default-members = [ ] [workspace.package] -version = "2026.3.2" +version = "2026.3.3" [profile.profiling] inherits = "release" diff --git a/VERSION b/VERSION index 4129f6b3e..d96d727b7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2026.3.2 +2026.3.3 diff --git a/crates/devolutions-pedm-shell-ext/AppxManifest.xml b/crates/devolutions-pedm-shell-ext/AppxManifest.xml index 0543779bf..a8a9b560e 100644 --- a/crates/devolutions-pedm-shell-ext/AppxManifest.xml +++ b/crates/devolutions-pedm-shell-ext/AppxManifest.xml @@ -11,7 +11,7 @@ xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop4 desktop5 uap10 com"> + Version="2026.3.3.0" /> Devolutions Agent Devolutions diff --git a/dotnet/DesktopAgent/DesktopAgent.csproj b/dotnet/DesktopAgent/DesktopAgent.csproj index 4452ac3c6..db205cf7d 100644 --- a/dotnet/DesktopAgent/DesktopAgent.csproj +++ b/dotnet/DesktopAgent/DesktopAgent.csproj @@ -6,7 +6,7 @@ DevolutionsDesktopAgent Devolutions Agent latest - 2026.3.2.0 + 2026.3.3.0 Devolutions Copyright © 2025 Devolutions Agent diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index afcba7c5a..f606a444c 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -689,7 +689,7 @@ dependencies = [ [[package]] name = "devolutions-gateway" -version = "2026.3.2" +version = "2026.3.3" dependencies = [ "anyhow", "async-trait", diff --git a/package/AgentLinux/CHANGELOG.md b/package/AgentLinux/CHANGELOG.md index 20ce97f50..37af9aa5e 100644 --- a/package/AgentLinux/CHANGELOG.md +++ b/package/AgentLinux/CHANGELOG.md @@ -1,5 +1,9 @@ # Packaging changelog +## 2026.3.3 (2026-10-14) + +- No changes. + ## 2026.3.2 (2026-10-09) - No changes. diff --git a/package/Linux/CHANGELOG.md b/package/Linux/CHANGELOG.md index 1e2b2f10b..dd78ddbae 100644 --- a/package/Linux/CHANGELOG.md +++ b/package/Linux/CHANGELOG.md @@ -1,5 +1,9 @@ # Packaging changelog +## 2026.3.3 (2026-10-14) + +- No changes. + ## 2026.3.2 (2026-10-09) - No changes. diff --git a/powershell/DevolutionsGateway/DevolutionsGateway.psd1 b/powershell/DevolutionsGateway/DevolutionsGateway.psd1 index 5c486fe69..ffba8d742 100644 --- a/powershell/DevolutionsGateway/DevolutionsGateway.psd1 +++ b/powershell/DevolutionsGateway/DevolutionsGateway.psd1 @@ -7,7 +7,7 @@ RootModule = 'DevolutionsGateway.psm1' # Version number of this module. - ModuleVersion = '2026.3.2' + ModuleVersion = '2026.3.3' # Supported PSEditions CompatiblePSEditions = 'Desktop', 'Core'