Release #79
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| run: | |
| description: 'The Package workflow run to release' | |
| required: true | |
| dry-run: | |
| description: 'If true, the workflow only indicates which artifacts would be uploaded' | |
| required: true | |
| type: boolean | |
| default: true | |
| workflow_call: | |
| inputs: | |
| dispatch: | |
| description: "Marker to indicate that the workflow was dispatched via workflow_call" | |
| type: string | |
| required: false | |
| default: "workflow_call" | |
| dry-run: | |
| description: 'If true, the workflow only indicates which artifacts would be uploaded' | |
| required: true | |
| type: boolean | |
| default: true | |
| concurrency: gateway-release | |
| jobs: | |
| preflight: | |
| name: Preflight | |
| runs-on: ubuntu-latest | |
| outputs: | |
| run: ${{ steps.get-run.outputs.run }} | |
| version: ${{ steps.get-version.outputs.version }} | |
| skip-publishing: ${{ steps.check-release.outputs.skip-publishing }} | |
| steps: | |
| ## workflow_dispatch: The run_id is read from the inputs | |
| ## workflow_call: The run_id is the current run_id | |
| - name: Get run | |
| id: get-run | |
| shell: pwsh | |
| run: | | |
| if ('${{ github.event.inputs.run }}') { | |
| echo "run=${{ github.event.inputs.run }}" >> $Env:GITHUB_OUTPUT | |
| } else { | |
| echo "run=${{ github.run_id }}" >> $Env:GITHUB_OUTPUT | |
| } | |
| - name: Get dry run | |
| id: get-dry-run | |
| shell: pwsh | |
| run: | | |
| $DryRun = "false" | |
| if ('${{ inputs.dry-run }}') { | |
| $DryRun = "${{ inputs.dry-run }}" | |
| } | |
| if ([System.Convert]::ToBoolean($DryRun)) { | |
| echo "::notice::This is a dry run; publishing will be skipped" | |
| } else { | |
| echo "::warning::This is not a dry run, release will be published!" | |
| } | |
| - name: Download version | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: gh run download ${{ steps.get-run.outputs.run }} -n version --repo $Env:GITHUB_REPOSITORY | |
| - name: Get version | |
| id: get-version | |
| shell: pwsh | |
| run: | | |
| $Version = Get-Content VERSION -TotalCount 1 | |
| echo "version=$Version" >> $Env:GITHUB_OUTPUT | |
| echo "::notice::Releasing artifacts for version $Version from run ${{ steps.get-run.outputs.run }}" | |
| ## If we already released this version to GitHub, publishing will be skipped | |
| - name: Check GitHub releases | |
| id: check-release | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $Output = (gh release list --repo $Env:GITHUB_REPOSITORY) | Out-String | |
| $Releases = ( $Output -split '\r?\n' ).Trim() | |
| $Versions = ForEach($Release in $Releases) { | |
| $Version = ( $Release -Split '\s+' ).Trim() | |
| $Version = $Version.TrimStart("v") | |
| $Version[0] | |
| } | |
| $SkipPublishing = 'false' | |
| if ($Versions -Contains "${{ steps.get-version.outputs.version }}") { | |
| echo "::warning::GitHub already has a release version ${{ steps.get-version.outputs.version }}; publishing will be skipped" | |
| $SkipPublishing = 'true' | |
| } | |
| echo "skip-publishing=$SkipPublishing" >> $Env:GITHUB_OUTPUT | |
| container: | |
| name: Container [${{ matrix.os }} ${{ matrix.base-image }}] | |
| runs-on: ${{ matrix.runner }} | |
| environment: publish-prod | |
| needs: preflight | |
| if: needs.preflight.outputs.skip-publishing == 'false' || ${{ inputs.dry-run }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| arch: [ x86_64 ] | |
| os: [ linux ] | |
| base-image: [ bookworm-slim ] | |
| include: | |
| - os: linux | |
| runner: ubuntu-latest | |
| steps: | |
| - name: Download artifacts | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: gh run download ${{ needs.preflight.outputs.run }} -n webapp-client -n docker -n devolutions-gateway -n native-libs --repo $Env:GITHUB_REPOSITORY | |
| ## workflow_call: The same artifacts persist across the entire run, so the PowerShell/DevolutionsGateway directory will still exist from the CI workflow | |
| - name: Manage artifacts | |
| shell: pwsh | |
| run: Remove-Item -Path (Join-Path devolutions-gateway PowerShell DevolutionsGateway) -Recurse -ErrorAction Ignore | |
| - name: Prepare artifacts | |
| id: prepare-artifacts | |
| shell: pwsh | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $PkgDir = Join-Path docker $Env:RUNNER_OS # RUNNER_OS is camelcase | |
| echo "package-path=$PkgDir" >> $Env:GITHUB_OUTPUT | |
| Write-Host "PkgDir = $PkgDir" | |
| Get-ChildItem -Path "$PkgDir" | |
| $SourceFileName = "DevolutionsGateway_$($Env:RUNNER_OS)_${{ needs.preflight.outputs.version }}_${{ matrix.arch }}" | |
| $TargetFileName = "devolutions-gateway" | |
| Write-Host "SourceFileName = $SourceFileName" | |
| Write-Host "TargetFileName = $TargetFileName" | |
| $SourcePath = Get-ChildItem -Recurse -Filter $SourceFileName -File -Path devolutions-gateway | |
| $TargetPath = Join-Path $PkgDir $TargetFileName | |
| Write-Host "SourcePath = $SourcePath" | |
| Write-Host "TargetPath = $TargetPath" | |
| Copy-Item -Path $SourcePath -Destination $TargetPath | |
| if ($Env:RUNNER_OS -eq "Linux") { | |
| Invoke-Expression "chmod +x $TargetPath" | |
| } | |
| $XmfFileName = "libxmf.so" | |
| $XmfSourcePath = Get-ChildItem -Recurse -Filter $XmfFileName -File -Path native-libs | |
| $XmfTargetPath = Join-Path $PkgDir $XmfFileName | |
| Write-Host "XmfSourcePath = $XmfSourcePath" | |
| Write-Host "XmfTargetPath = $XmfTargetPath" | |
| Copy-Item -Path $XmfSourcePath -Destination $XmfTargetPath | |
| $WebAppArchive = Get-ChildItem -Recurse -Filter "devolutions_gateway_webapp_*.tar.gz" | Select-Object -First 1 | |
| $TargetPath = Join-Path $PkgDir "webapp" "client" | |
| Write-Host "WebAppArchive = $WebAppArchive" | |
| Write-Host "TargetPath = $TargetPath" | |
| New-Item -ItemType Directory -Path $TargetPath | |
| tar -xvzf $WebAppArchive.FullName -C $TargetPath --strip-components=1 | |
| $PowerShellArchive = Get-ChildItem -Recurse -Filter "DevolutionsGateway-ps-*.tar" | Select-Object -First 1 | |
| tar -xvf "$PowerShellArchive" -C "$PkgDir" | |
| - name: Build container | |
| id: build-container | |
| shell: pwsh | |
| working-directory: ${{ steps.prepare-artifacts.outputs.package-path }} | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $ImageName = "devolutions/devolutions-gateway:${{ needs.preflight.outputs.version }}-${{ matrix.base-image }}" | |
| docker build -t "$ImageName" . | |
| echo "image-name=$ImageName" >> $Env:GITHUB_OUTPUT | |
| Get-ChildItem -Recurse | |
| - name: Push container | |
| shell: pwsh | |
| working-directory: ${{ steps.prepare-artifacts.outputs.package-path }} | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| echo ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | docker login -u devolutionsbot --password-stdin | |
| $DockerPushCmd = 'docker push ${{ steps.build-container.outputs.image-name }}' | |
| Write-Host $DockerPushCmd | |
| $DryRun = [System.Convert]::ToBoolean('${{ inputs.dry-run }}') | |
| if (-Not $DryRun) { | |
| Invoke-Expression $DockerPushCmd | |
| } | |
| github-release: | |
| name: GitHub release | |
| runs-on: ubuntu-latest | |
| environment: publish-prod | |
| needs: preflight | |
| if: needs.preflight.outputs.skip-publishing == 'false' || ${{ inputs.dry-run }} | |
| steps: | |
| - name: Configure runner | |
| run: cargo install parse-changelog | |
| - name: Download artifacts | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: gh run download ${{ needs.preflight.outputs.run }} -n jetsocat -n devolutions-gateway -n devolutions-agent -n webapp-client -n changelog --repo $Env:GITHUB_REPOSITORY | |
| - name: Manage artifacts | |
| shell: pwsh | |
| run: | | |
| # workflow_call: The same artifacts persist across the entire run, so the PowerShell/DevolutionsGateway directory will still exist from the CI workflow | |
| # FIXME: I suspect this line is no longer required. | |
| Remove-Item -Path (Join-Path devolutions-gateway PowerShell DevolutionsGateway) -Recurse -ErrorAction Ignore | |
| # Devolutions Agent on Linux does not have any useful feature yet, so we filter out the Linux artifacts. | |
| Remove-Item -Path (Join-Path devolutions-agent linux) -Recurse -ErrorAction Ignore | |
| - name: Create GitHub release | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $Version = "${{ needs.preflight.outputs.version }}" | |
| $HashPath = 'checksums' | |
| $Files = Get-ChildItem -Recurse -File -Exclude 'CHANGELOG.md', '*.dll' | % { Get-FileHash -Algorithm SHA256 $_.FullName } | |
| $Files | % { "$($_.Hash) $(Split-Path $_.Path -leaf)" } | Out-File -FilePath $HashPath -Append -Encoding ASCII | |
| echo "::group::checksums" | |
| Get-Content $HashPath | |
| echo "::endgroup::" | |
| $ChangesPath = 'changes' | |
| parse-changelog $(Join-Path changelog CHANGELOG.md) $Version | Out-File -Encoding UTF8NoBOM $ChangesPath | |
| echo "::group::changes" | |
| Get-Content $ChangesPath | |
| echo "::endgroup::" | |
| $GhCmd = $(@('gh', 'release', 'create', "v$Version", "--repo", $Env:GITHUB_REPOSITORY, "--notes-file", $ChangesPath, $HashPath) + $Files.Path) -Join ' ' | |
| Write-Host $GhCmd | |
| $DryRun = [System.Convert]::ToBoolean('${{ inputs.dry-run }}') | |
| if (-Not $DryRun) { | |
| Invoke-Expression $GhCmd | |
| } | |
| psgallery-release: | |
| name: PowerShell release | |
| runs-on: ubuntu-latest | |
| environment: publish-prod | |
| needs: preflight | |
| if: needs.preflight.outputs.skip-publishing == 'false' || ${{ inputs.dry-run }} | |
| steps: | |
| - name: Download artifacts | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: gh run download ${{ needs.preflight.outputs.run }} -n devolutions-gateway --repo $Env:GITHUB_REPOSITORY | |
| ## workflow_call: The same artifacts persist across the entire run, so the PowerShell/DevolutionsGateway directory will still exist from the CI workflow | |
| - name: Manage artifacts | |
| shell: pwsh | |
| run: Remove-Item -Path (Join-Path PowerShell DevolutionsGateway) -Recurse -ErrorAction Ignore | |
| - name: Install PSResourceGet | |
| shell: pwsh | |
| run: | | |
| Install-PSResource Microsoft.PowerShell.PSResourceGet -Scope CurrentUser -TrustRepository | |
| - name: Publish PowerShell module | |
| shell: pwsh | |
| run: | | |
| $Archive = Get-ChildItem -Recurse -Filter "*-ps-*.tar" -File | |
| Write-Host "Archive = $Archive" | |
| tar -xvf "$Archive" -C './PowerShell' | |
| Get-ChildItem -Path "./PowerShell" -Recurse | |
| $PublishCmd = @('Publish-PSResource', '-Force', '-Repository', 'PSGallery', '-Path', (Join-Path PowerShell DevolutionsGateway), '-ApiKey', '${{ secrets.PS_GALLERY_NUGET_API_KEY }}') | |
| $DryRun = [System.Convert]::ToBoolean('${{ inputs.dry-run }}') | |
| if ($DryRun) { | |
| $PublishCmd += '-WhatIf' | |
| } | |
| $PublishCmd = $PublishCmd -Join ' ' | |
| Write-Host "PublishCmd = $PublishCmd" | |
| try { | |
| Invoke-Expression $PublishCmd | |
| } catch { | |
| if ($_.Exception.Message -ilike "*cannot be published as the current version*is already available in the repository*") { | |
| echo "::warning::PowerShell module not published; this version is already listed on PSGallery" | |
| } else { | |
| Write-Error $_ | |
| exit 1 | |
| } | |
| } | |
| onedrive-gateway: | |
| name: OneDrive (Devolutions Gateway) | |
| runs-on: ubuntu-latest | |
| needs: preflight | |
| if: needs.preflight.outputs.skip-publishing == 'false' || ${{ inputs.dry-run }} | |
| environment: onedrive-upload # for OneDrive secrets | |
| steps: | |
| - name: Check out Devolutions/actions | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: Devolutions/actions | |
| ref: v1 | |
| token: ${{ secrets.DEVOLUTIONSBOT_TOKEN }} | |
| path: ./.github/workflows | |
| ## Devolutions Toolbox is required for OneDrive uploading | |
| - name: Install Devolutions Toolbox | |
| uses: ./.github/workflows/toolbox-install | |
| with: | |
| github_token: ${{ secrets.DEVOLUTIONSBOT_TOKEN }} | |
| - name: Download artifacts | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: gh run download ${{ needs.preflight.outputs.run }} -n devolutions-gateway --repo $Env:GITHUB_REPOSITORY | |
| - name: Prepare upload | |
| id: prepare | |
| shell: pwsh | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $destinationFolder = "${{ runner.temp }}/artifacts" | |
| $version="${{ needs.preflight.outputs.version }}" | |
| # Note that ".0" is appended here (required by release tooling downstream) | |
| $versionFull="$version.0" | |
| echo "version=${versionFull}" >> $Env:GITHUB_OUTPUT | |
| echo "files-to-upload=$destinationFolder" >> $Env:GITHUB_OUTPUT | |
| New-Item -Path "$destinationFolder" -ItemType "directory" | |
| Move-Item -Path "./windows/x86_64/DevolutionsGateway-x86_64-${version}.msi" -Destination "$destinationFolder/DevolutionsGateway-x86_64-${versionFull}.msi" | |
| Move-Item -Path "./windows/x86_64/DevolutionsGateway_Windows_${version}_x86_64.pdb" -Destination "$destinationFolder/DevolutionsGateway-x86_64-${versionFull}.pdb" | |
| Move-Item -Path "./linux/x86_64/devolutions-gateway_${version}-1_amd64.deb" -Destination "$destinationFolder/devolutions-gateway_${versionFull}_amd64.deb" | |
| Move-Item -Path "./linux/x86_64/devolutions-gateway_${version}-1_x86_64.rpm" -Destination "$destinationFolder/devolutions-gateway_${versionFull}_x86_64.rpm" | |
| - name: Upload to OneDrive | |
| uses: ./.github/workflows/onedrive-upload | |
| if: (needs.preflight.outputs.skip-publishing == 'false') && (inputs.dry-run == false) | |
| with: | |
| azure_client_id: ${{ secrets.ONEDRIVE_AUTOMATION_CLIENT_ID }} | |
| azure_client_secret: ${{ secrets.ONEDRIVE_AUTOMATION_CLIENT_SECRET }} | |
| conflict_behavior: fail | |
| destination_path: /Gateway/${{ steps.prepare.outputs.version }} | |
| remote: releases | |
| source_path: ${{ steps.prepare.outputs.files-to-upload }} | |
| onedrive-agent: | |
| name: OneDrive (Devolutions Agent) | |
| runs-on: ubuntu-latest | |
| needs: preflight | |
| if: needs.preflight.outputs.skip-publishing == 'false' || ${{ inputs.dry-run }} | |
| environment: onedrive-upload # for OneDrive secrets | |
| steps: | |
| - name: Check out Devolutions/actions | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: Devolutions/actions | |
| ref: v1 | |
| token: ${{ secrets.DEVOLUTIONSBOT_TOKEN }} | |
| path: ./.github/workflows | |
| ## Devolutions Toolbox is required for OneDrive uploading | |
| - name: Install Devolutions Toolbox | |
| uses: ./.github/workflows/toolbox-install | |
| with: | |
| github_token: ${{ secrets.DEVOLUTIONSBOT_TOKEN }} | |
| - name: Download artifacts | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: gh run download ${{ needs.preflight.outputs.run }} -n devolutions-agent --repo $Env:GITHUB_REPOSITORY | |
| - name: Prepare upload | |
| id: prepare | |
| shell: pwsh | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $destinationFolder = "${{ runner.temp }}/artifacts" | |
| $version="${{ needs.preflight.outputs.version }}" | |
| # Note that ".0" is appended here (required by release tooling downstream) | |
| $versionFull="$version.0" | |
| echo "version=${versionFull}" >> $Env:GITHUB_OUTPUT | |
| echo "files-to-upload=$destinationFolder" >> $Env:GITHUB_OUTPUT | |
| New-Item -Path "$destinationFolder" -ItemType "directory" | |
| Move-Item -Path "./windows/x86_64/DevolutionsAgent-x86_64-${version}.msi" -Destination "$destinationFolder/DevolutionsAgent-x86_64-${versionFull}.msi" | |
| Move-Item -Path "./windows/x86_64/DevolutionsAgent-x86_64-${version}.symbols.zip" -Destination "$destinationFolder/DevolutionsAgent-x86_64-${versionFull}.symbols.zip" | |
| Move-Item -Path "./linux/x86_64/devolutions-agent_${version}-1_amd64.deb" -Destination "$destinationFolder/devolutions-agent_${versionFull}_amd64.deb" | |
| Move-Item -Path "./linux/x86_64/devolutions-agent_${version}-1_x86_64.rpm" -Destination "$destinationFolder/devolutions-agent_${versionFull}_x86_64.rpm" | |
| - name: Upload to OneDrive | |
| uses: ./.github/workflows/onedrive-upload | |
| if: (needs.preflight.outputs.skip-publishing == 'false') && (inputs.dry-run == false) | |
| with: | |
| azure_client_id: ${{ secrets.ONEDRIVE_AUTOMATION_CLIENT_ID }} | |
| azure_client_secret: ${{ secrets.ONEDRIVE_AUTOMATION_CLIENT_SECRET }} | |
| conflict_behavior: fail | |
| destination_path: /Agent/${{ steps.prepare.outputs.version }} | |
| remote: releases | |
| source_path: ${{ steps.prepare.outputs.files-to-upload }} | |
| remove-labels: | |
| name: Remove release-required labels | |
| runs-on: ubuntu-latest | |
| if: needs.preflight.outputs.skip-publishing == 'false' || ${{ inputs.dry-run }} | |
| needs: | |
| - container | |
| - github-release | |
| - psgallery-release | |
| - onedrive-gateway | |
| - onedrive-agent | |
| steps: | |
| - name: Check out ${{ github.repository }} | |
| uses: actions/checkout@v4 | |
| - name: Remove labels | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: ./ci/remove-labels.ps1 -Label 'release-required' | |