Publish libraries #164
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: Publish libraries | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: Dry run | |
| required: true | |
| type: boolean | |
| default: true | |
| schedule: | |
| - cron: '49 3 * * 1' # 3:49 AM UTC every Monday | |
| jobs: | |
| preflight: | |
| name: Preflight | |
| runs-on: ubuntu-latest | |
| outputs: | |
| dry_run: ${{ steps.get-dry-run.outputs.dry_run }} | |
| steps: | |
| - name: Get dry run | |
| id: get-dry-run | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $IsDryRun = '${{ github.event.inputs.dry_run }}' -Eq 'true' -Or '${{ github.event_name }}' -Eq 'schedule' | |
| if ($IsDryRun) { | |
| echo "dry_run=true" >> $Env:GITHUB_OUTPUT | |
| } else { | |
| echo "dry_run=false" >> $Env:GITHUB_OUTPUT | |
| } | |
| shell: pwsh | |
| nuget-build: | |
| name: NuGet package build [${{matrix.library}}] | |
| runs-on: windows-2022 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| library: [ dotnet-client, dotnet-subscriber, utils, pedm-dotnet-client ] | |
| include: | |
| - library: dotnet-client | |
| libpath: ./devolutions-gateway/openapi/dotnet-client | |
| - library: dotnet-subscriber | |
| libpath: ./devolutions-gateway/openapi/dotnet-subscriber | |
| - library: utils | |
| libpath: ./utils/dotnet | |
| - library: pedm-dotnet-client | |
| libpath: ./crates/devolutions-pedm/openapi/dotnet-client | |
| steps: | |
| - name: Check out ${{ github.repository }} | |
| uses: actions/checkout@v4 | |
| - name: Build | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $Path = '${{matrix.libpath}}' | |
| & "$Path/build.ps1" | |
| New-Item -ItemType "directory" -Path . -Name "nuget-packages" | |
| Get-ChildItem -Path $Path -Recurse -Include '*.nupkg' | ForEach { Copy-Item $_ "./nuget-packages" } | |
| Get-ChildItem -Path $Path -Recurse -Include '*.snupkg' | ForEach { Copy-Item $_ "./nuget-packages" } | |
| shell: pwsh | |
| - name: Upload packages | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: nupkg-${{matrix.library}} | |
| path: | | |
| nuget-packages/*.nupkg | |
| nuget-packages/*.snupkg | |
| nuget-merge: | |
| name: NuGet merge artifacts | |
| needs: [nuget-build] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Merge Artifacts | |
| uses: actions/upload-artifact/merge@v4 | |
| with: | |
| name: nupkg | |
| pattern: nupkg-* | |
| delete-merged: true | |
| npm-build: | |
| name: NPM package build [${{matrix.library}}] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| library: [ ts-angular-client, multi-video-player, shadow-player ] | |
| include: | |
| - library: ts-angular-client | |
| libpath: ./devolutions-gateway/openapi/ts-angular-client | |
| - library: multi-video-player | |
| libpath: ./webapp/packages/multi-video-player | |
| - library: shadow-player | |
| libpath: ./webapp/packages/shadow-player | |
| steps: | |
| - name: Check out ${{ github.repository }} | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'pnpm' | |
| cache-dependency-path: 'webapp/pnpm-lock.yaml' | |
| - name: Build | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $Path = '${{matrix.libpath}}' | |
| & "$Path/build.ps1" | |
| New-Item -ItemType "directory" -Path . -Name "npm-packages" | |
| Get-ChildItem -Path $Path -Recurse *.tgz | ForEach { Copy-Item $_ "./npm-packages" } | |
| shell: pwsh | |
| - name: Upload packages | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: npm-${{matrix.library}} | |
| path: npm-packages/*.tgz | |
| npm-merge: | |
| name: NPM merge artifacts | |
| runs-on: ubuntu-latest | |
| needs: [npm-build] | |
| steps: | |
| - name: Merge Artifacts | |
| uses: actions/upload-artifact/merge@v4 | |
| with: | |
| name: npm | |
| pattern: npm-* | |
| delete-merged: true | |
| nuget-publish: | |
| name: Publish NuGet packages | |
| environment: publish-prod | |
| if: ${{ needs.preflight.outputs.dry_run == 'false' }} | |
| needs: [preflight, nuget-merge] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Download NuGet packages artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: nupkg | |
| path: nuget-packages | |
| - name: NuGet login (OIDC) | |
| id: nuget-login | |
| uses: NuGet/login@v1 | |
| with: | |
| user: ${{ secrets.NUGET_BOT_USERNAME }} | |
| - name: Publish to nuget.org | |
| run: | | |
| Set-PSDebug -Trace 1 | |
| $Files = Get-ChildItem -Recurse nuget-packages/*.nupkg | |
| foreach ($File in $Files) { | |
| $PushCmd = @( | |
| 'dotnet', | |
| 'nuget', | |
| 'push', | |
| "$File", | |
| '--api-key', | |
| '${{ steps.nuget-login.outputs.NUGET_API_KEY }}', | |
| '--source', | |
| 'https://api.nuget.org/v3/index.json', | |
| '--skip-duplicate' | |
| ) | |
| Write-Host "Publishing $($File.Name)..." | |
| $PushCmd = $PushCmd -Join ' ' | |
| Invoke-Expression $PushCmd | |
| } | |
| shell: pwsh | |
| npm-publish: | |
| name: Publish NPM packages | |
| environment: publish-prod | |
| if: ${{ needs.preflight.outputs.dry_run == 'false' }} | |
| needs: [preflight, npm-merge, npm-build] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: '24' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Update npm to latest version | |
| run: | | |
| npm install npm@latest | |
| npm -v | |
| - name: Download NPM packages artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: npm | |
| path: npm-packages | |
| - name: Publish | |
| run: | | |
| for tarball in npm-packages/*.tgz; do | |
| echo "Publishing $(basename $tarball)..." | |
| tmp_dir=$(mktemp -d) | |
| echo "Temporary directory to extract package tarball: $tmp_dir" | |
| tar -xzf "$tarball" -C "$tmp_dir" package/package.json | |
| name=$(node -p "require('$tmp_dir/package/package.json').name") | |
| local_version=$(node -p "require('$tmp_dir/package/package.json').version") | |
| echo "Found package $name" | |
| echo "Local version is $local_version" | |
| remote_version=$(npm view "$name" version 2>/dev/null || echo "none") | |
| echo "Latest version on registry is $remote_version" | |
| if [ "$local_version" = "$remote_version" ]; then | |
| echo "Local and distant versions are identical. Skip publishing." | |
| else | |
| echo "Publishing..." | |
| npm publish "$tarball" --access public --provenance | |
| fi | |
| rm -rf "$tmp_dir" | |
| done | |
| shell: bash | |
| env: | |
| NODE_AUTH_TOKEN: '' # workaround for https://github.com/actions/setup-node/issues/1440 | |
| - name: Update Artifactory Cache | |
| run: gh workflow run update-artifactory-cache.yml --repo Devolutions/scheduled-tasks --field package_name="gateway-client" | |
| env: | |
| GH_TOKEN: ${{ secrets.DEVOLUTIONSBOT_WRITE_TOKEN }} | |
| remove-labels: | |
| name: Remove publish-required labels | |
| if: ${{ needs.preflight.outputs.dry_run == 'false' }} | |
| needs: [preflight, nuget-build, npm-publish] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out ${{ github.repository }} | |
| uses: actions/checkout@v4 | |
| - name: Remove labels | |
| run: ./ci/remove-labels.ps1 -Label 'publish-required' | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| notify: | |
| name: Notify failure | |
| if: ${{ always() && contains(needs.*.result, 'failure') && github.event_name == 'schedule' }} | |
| needs: [npm-build, nuget-merge] | |
| runs-on: ubuntu-latest | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_ARCHITECTURE }} | |
| SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK | |
| steps: | |
| - name: Send slack notification | |
| id: slack | |
| uses: slackapi/slack-github-action@v1.24.0 | |
| with: | |
| payload: | | |
| { | |
| "blocks": [ | |
| { | |
| "type": "section", | |
| "text": { | |
| "type": "mrkdwn", | |
| "text": "*${{ github.repository }}* :fire::fire::fire::fire::fire: \n The scheduled build for *${{ github.repository }}* is <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|broken>" | |
| } | |
| } | |
| ] | |
| } |