diff --git a/.github/workflows/build-macos.yaml b/.github/workflows/build-macos.yaml index ae6b24352..e21d5c97b 100644 --- a/.github/workflows/build-macos.yaml +++ b/.github/workflows/build-macos.yaml @@ -12,6 +12,8 @@ on: - v*.*.* env: + CARGO_TERM_COLOR: always + # sccache SCCACHE_GHA_ENABLED: "true" RUSTC_WRAPPER: "sccache" SQLX_OFFLINE: "1" @@ -39,7 +41,8 @@ jobs: echo "DEFGUARD_CLIENT_BUILD_VERSION=${GITHUB_REF_NAME#v}" >> ${GITHUB_ENV} fi - - uses: actions/setup-node@v6 + - name: Install NodeJS + uses: actions/setup-node@v6 with: node-version-file: new-ui/.nvmrc diff --git a/.github/workflows/nightly-build-1x.yaml b/.github/workflows/nightly-build-1x.yaml new file mode 100644 index 000000000..2260106af --- /dev/null +++ b/.github/workflows/nightly-build-1x.yaml @@ -0,0 +1,205 @@ +name: "Nightly build (main layout)" + +on: + workflow_call: + inputs: + branch: + required: true + type: string + s3_bucket: + required: true + type: string + s3_prefix: + required: true + type: string + aws_region: + required: true + type: string + + outputs: + version: + value: ${{ jobs.build-linux.outputs.version }} + +env: + S3_BUCKET: ${{ inputs.s3_bucket }} + S3_PREFIX: ${{ inputs.s3_prefix }} + AWS_DEFAULT_REGION: ${{ inputs.aws_region }} + +jobs: + build-linux: + outputs: + version: ${{ steps.version.outputs.version }} + env: + CARGO_TERM_COLOR: always + # sccache + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" + runs-on: + - self-hosted + - Linux + - ${{ matrix.architecture }} + strategy: + fail-fast: false + matrix: + architecture: [ARM64, X64] + include: + - architecture: ARM64 + deb_arch: arm64 + binary_arch: aarch64 + - architecture: X64 + deb_arch: amd64 + binary_arch: x86_64 + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ inputs.branch }} + submodules: recursive + + - name: Install NodeJS + uses: actions/setup-node@v6 + with: + node-version: 26 + + - name: Install pnpm + uses: pnpm/action-setup@v6 + with: + cache: true + version: 11 + run_install: false + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> ${GITHUB_ENV} + + # Change to '--frozen-lockfile' once this gets fixed: + # https://github.com/pnpm/action-setup/issues/40 + - name: Install Node dependencies + run: pnpm install --no-frozen-lockfile + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.10 + + - name: Install Linux dependencies + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf libssl-dev libxdo-dev unzip protobuf-compiler libprotobuf-dev rpm awscli jq + + - name: Write build version + id: version + run: | + VERSION=$(jq -r .version src-tauri/tauri.conf.json) + echo Version: $VERSION + echo "VERSION=$VERSION" >> ${GITHUB_ENV} + echo "version=$VERSION" >> ${GITHUB_OUTPUT} + BRANCH="${{ inputs.branch }}" + echo "BRANCH=${BRANCH//\//-}" >> ${GITHUB_ENV} + echo "SHA=$(git rev-parse --short HEAD)" >> ${GITHUB_ENV} + + - name: Build packages + uses: tauri-apps/tauri-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: --bundles deb,rpm --ignore-version-mismatches + + - name: Upload DEB and RPM to S3 + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_NIGHTLY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY_NIGHTLY }} + run: | + NAME="defguard-client-${{ matrix.binary_arch }}-${SHA}" + aws s3 cp --acl public-read \ + "src-tauri/target/release/bundle/deb/defguard-client_${VERSION}_${{ matrix.deb_arch }}.deb" \ + "s3://${S3_BUCKET}/${S3_PREFIX}/${BRANCH}/${NAME}.deb" + aws s3 cp --acl public-read \ + "src-tauri/target/release/bundle/rpm/defguard-client-${VERSION}-1.${{ matrix.binary_arch }}.rpm" \ + "s3://${S3_BUCKET}/${S3_PREFIX}/${BRANCH}/${NAME}.rpm" + + build-macos-pkg: + env: + CARGO_TERM_COLOR: always + # sccache + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" + APPLE_SIGNING_IDENTITY: "Apple Distribution: defguard sp. z o.o. (82GZ7KN29J)" + APPLE_SIGNING_IDENTITY_INSTALLER: "3rd Party Mac Developer Installer: defguard sp. z o.o. (82GZ7KN29J)" + APPLE_PROVIDER_SHORT_NAME: "82GZ7KN29J" + APPLE_ID: "kamil@defguard.net" + APPLE_TEAM_ID: "82GZ7KN29J" + runs-on: + - self-hosted + - macOS + - native + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ inputs.branch }} + submodules: recursive + + - name: Write build version + run: | + VERSION=$(jq -r .version src-tauri/tauri.conf.json) + echo Version: $VERSION + echo "VERSION=$VERSION" >> ${GITHUB_ENV} + BRANCH="${{ inputs.branch }}" + echo "BRANCH=${BRANCH//\//-}" >> ${GITHUB_ENV} + echo "SHA=$(git rev-parse --short HEAD)" >> ${GITHUB_ENV} + + - name: Install NodeJS + uses: actions/setup-node@v6 + with: + node-version: 26 + + - name: Install pnpm + uses: pnpm/action-setup@v6 + with: + cache: true + version: 11 + + # Change to '--frozen-lockfile' once this gets fixed: + # https://github.com/pnpm/action-setup/issues/40 + - name: Install Node dependencies + run: pnpm install --no-frozen-lockfile + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-apple-darwin,x86_64-apple-darwin + + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.10 + + - name: Set build number + run: | + sed -i '' "s,@BUILD_NUMBER@,${{ github.run_number }}," src-tauri/tauri.conf.json + sed -i '' "s,@BUILD_NUMBER@,${{ github.run_number }}," swift/extension/VPNExtension.xcodeproj/project.pbxproj + + - name: Unlock keychain + run: security unlock-keychain -p "${{ secrets.BUILD_KEYCHAIN_PASSWORD }}" build.keychain + + - name: Build app + uses: tauri-apps/tauri-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: --target universal-apple-darwin --ignore-version-mismatches + + - name: Build installation package + run: | + xcrun productbuild --keychain build.keychain \ + --sign "${{ env.APPLE_SIGNING_IDENTITY_INSTALLER }}" \ + --component "src-tauri/target/universal-apple-darwin/release/bundle/macos/Defguard.app" \ + /Applications defguard-client.pkg + + - name: Upload PKG to S3 + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_NIGHTLY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY_NIGHTLY }} + run: | + export PATH="/opt/homebrew/bin:/usr/local/bin:${PATH}" + aws s3 cp --acl public-read defguard-client.pkg \ + "s3://${S3_BUCKET}/${S3_PREFIX}/${BRANCH}/defguard-client-universal-${SHA}.pkg" diff --git a/.github/workflows/nightly-build-2x.yaml b/.github/workflows/nightly-build-2x.yaml new file mode 100644 index 000000000..d3a6c7cd3 --- /dev/null +++ b/.github/workflows/nightly-build-2x.yaml @@ -0,0 +1,306 @@ +name: "Nightly build (new-ui layout)" + +on: + workflow_call: + inputs: + branch: + required: true + type: string + s3_bucket: + required: true + type: string + s3_prefix: + required: true + type: string + aws_region: + required: true + type: string + + outputs: + version: + value: ${{ jobs.build-linux.outputs.version }} + +env: + SQLX_OFFLINE: "1" + S3_BUCKET: ${{ inputs.s3_bucket }} + S3_PREFIX: ${{ inputs.s3_prefix }} + AWS_DEFAULT_REGION: ${{ inputs.aws_region }} + +jobs: + build-linux: + outputs: + version: ${{ steps.version.outputs.version }} + runs-on: + - self-hosted + - Linux + - ${{ matrix.architecture }} + strategy: + fail-fast: false + matrix: + architecture: [ARM64, X64] + include: + - architecture: ARM64 + deb_arch: arm64 + binary_arch: aarch64 + - architecture: X64 + deb_arch: amd64 + binary_arch: x86_64 + steps: + - uses: actions/checkout@v7 + with: + ref: ${{ inputs.branch }} + submodules: recursive + + - uses: actions/setup-node@v6 + with: + node-version-file: new-ui/.nvmrc + + - uses: pnpm/action-setup@v6 + with: + version: 11.11 + run_install: false + + - name: Get pnpm store directory + shell: bash + run: | + STORE_PATH=$(pnpm store path --silent) + mkdir -p "$STORE_PATH" + echo "STORE_PATH=$STORE_PATH" >> ${GITHUB_ENV} + + - name: Restore pnpm store cache + uses: actions/cache@v5 + with: + path: ${{ env.STORE_PATH }} + key: pnpm-store-${{ runner.os }}-${{ hashFiles('new-ui/pnpm-lock.yaml') }} + restore-keys: | + pnpm-store-${{ runner.os }}- + + - name: Install Node dependencies for new UI + run: | + cd new-ui + pnpm install --no-frozen-lockfile + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + + - name: Install tauri-cli + run: cargo install tauri-cli --locked + + - name: Install Linux dependencies + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf libssl-dev libxdo-dev unzip protobuf-compiler libprotobuf-dev rpm awscli jq + + - name: Write build version + id: version + run: | + VERSION=$(jq -r .version src-tauri/tauri.conf.json) + echo Version: $VERSION + echo "VERSION=$VERSION" >> ${GITHUB_ENV} + echo "version=$VERSION" >> ${GITHUB_OUTPUT} + echo "DEFGUARD_CLIENT_BUILD_VERSION=${VERSION}-nightly" >> ${GITHUB_ENV} + BRANCH="${{ inputs.branch }}" + echo "BRANCH=${BRANCH//\//-}" >> ${GITHUB_ENV} + echo "SHA=$(git rev-parse --short HEAD)" >> ${GITHUB_ENV} + + - name: Build new UI + run: | + cd new-ui + pnpm build + + - name: Build packages + uses: tauri-apps/tauri-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tauriScript: cargo tauri + args: --bundles deb,rpm --ignore-version-mismatches + + - name: Upload DEB and RPM to S3 + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_NIGHTLY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY_NIGHTLY }} + run: | + NAME="defguard-client-${{ matrix.binary_arch }}-${SHA}" + aws s3 cp --acl public-read \ + "src-tauri/target/release/bundle/deb/defguard-client_${VERSION}_${{ matrix.deb_arch }}.deb" \ + "s3://${S3_BUCKET}/${S3_PREFIX}/${BRANCH}/${NAME}.deb" + aws s3 cp --acl public-read \ + "src-tauri/target/release/bundle/rpm/defguard-client-${VERSION}-1.${{ matrix.binary_arch }}.rpm" \ + "s3://${S3_BUCKET}/${S3_PREFIX}/${BRANCH}/${NAME}.rpm" + + build-macos-pkg: + runs-on: + - self-hosted + - macOS + - native + env: + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" + APPLE_SIGNING_IDENTITY: "Apple Distribution: defguard sp. z o.o. (82GZ7KN29J)" + APPLE_SIGNING_IDENTITY_INSTALLER: "3rd Party Mac Developer Installer: defguard sp. z o.o. (82GZ7KN29J)" + steps: + - uses: actions/checkout@v7 + with: + ref: ${{ inputs.branch }} + submodules: recursive + + - name: Write build version + run: | + VERSION=$(jq -r .version src-tauri/tauri.conf.json) + echo Version: $VERSION + echo "VERSION=$VERSION" >> ${GITHUB_ENV} + echo "DEFGUARD_CLIENT_BUILD_VERSION=${VERSION}-nightly" >> ${GITHUB_ENV} + BRANCH="${{ inputs.branch }}" + echo "BRANCH=${BRANCH//\//-}" >> ${GITHUB_ENV} + echo "SHA=$(git rev-parse --short HEAD)" >> ${GITHUB_ENV} + + - uses: actions/setup-node@v6 + with: + node-version-file: new-ui/.nvmrc + + - uses: pnpm/action-setup@v6 + with: + run_install: false + version: 11 + + - name: Get pnpm store directory + run: | + STORE_PATH=$(pnpm store path --silent) + mkdir -p "$STORE_PATH" + echo "STORE_PATH=$STORE_PATH" >> ${GITHUB_ENV} + + - name: Restore pnpm store cache + uses: actions/cache@v5 + with: + path: ${{ env.STORE_PATH }} + key: pnpm-store-${{ runner.os }}-${{ hashFiles('new-ui/pnpm-lock.yaml') }} + restore-keys: | + pnpm-store-${{ runner.os }}- + + - name: Install Node dependencies for New UI + run: | + cd new-ui + pnpm install --no-frozen-lockfile + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-apple-darwin,x86_64-apple-darwin + + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.10 + + - name: Install tauri-cli + run: cargo install tauri-cli --locked + + - name: Set build number + run: | + sed -i '' "s,@BUILD_NUMBER@,${{ github.run_number }}," swift/extension/VPNExtension.xcodeproj/project.pbxproj + sed -i '' "s,@BUILD_NUMBER@,${{ github.run_number }}," src-tauri/tauri.macos.conf.json + + - name: Build new UI + run: | + cd new-ui + pnpm build + + - name: Unlock keychain + run: | + security unlock-keychain -p "${{ secrets.BUILD_KEYCHAIN_PASSWORD }}" build.keychain + + - name: Build app + uses: tauri-apps/tauri-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tauriScript: cargo tauri + args: --config src-tauri/tauri.app.conf.json --target universal-apple-darwin --ignore-version-mismatches + + - name: Build installation package + run: | + xcrun productbuild --keychain build.keychain \ + --sign "${{ env.APPLE_SIGNING_IDENTITY_INSTALLER }}" \ + --component "src-tauri/target/universal-apple-darwin/release/bundle/macos/Defguard.app" \ + /Applications defguard-client.pkg + + - name: Upload PKG to S3 + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_NIGHTLY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY_NIGHTLY }} + run: | + export PATH="/opt/homebrew/bin:/usr/local/bin:${PATH}" + aws s3 cp --acl public-read defguard-client.pkg \ + "s3://${S3_BUCKET}/${S3_PREFIX}/${BRANCH}/defguard-client-universal-${SHA}.pkg" + + # build-windows-msi: + # runs-on: + # - self-hosted + # - Windows + # - X64 + # env: + # SCCACHE_GHA_ENABLED: "true" + # RUSTC_WRAPPER: "sccache" + # defaults: + # run: + # shell: powershell + # steps: + # - uses: actions/checkout@v7 + # with: + # ref: ${{ inputs.branch }} + # submodules: recursive + + # - name: Write build version + # run: | + # $version = (Get-Content src-tauri/tauri.conf.json -Raw | ConvertFrom-Json).version + # echo "Version: $version" + # echo "VERSION=$version" >> $env:GITHUB_ENV + # echo "DEFGUARD_CLIENT_BUILD_VERSION=$version-nightly" >> $env:GITHUB_ENV + # echo "BRANCH=$('${{ inputs.branch }}' -replace '/','-')" >> $env:GITHUB_ENV + # echo "SHA=$(git rev-parse --short HEAD)" >> $env:GITHUB_ENV + + # - uses: actions/setup-node@v6 + # with: + # node-version-file: new-ui/.nvmrc + + # - uses: pnpm/action-setup@v6 + # with: + # version: 11.11 + # run_install: false + + # - name: Install Node dependencies for new UI + # run: | + # cd new-ui + # pnpm install --no-frozen-lockfile + + # - name: Install Rust stable + # uses: dtolnay/rust-toolchain@stable + + # - name: Run sccache-cache + # uses: mozilla-actions/sccache-action@v0.0.10 + + # - name: Install tauri-cli + # run: cargo install tauri-cli --locked + + # - name: Build new UI + # run: | + # cd new-ui + # pnpm build + + # - name: Build service and CLI binaries + # run: cargo build --release --manifest-path src-tauri/Cargo.toml -p defguard-cli -p defguard-client-service + + # - name: Build MSI + # uses: tauri-apps/tauri-action@v0.5.23 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # tauriScript: cargo tauri + # args: "--bundles msi" + + # - name: Upload MSI to S3 + # env: + # AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_NIGHTLY }} + # AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY_NIGHTLY }} + # run: | + # aws s3 cp --acl public-read "src-tauri/target/release/bundle/msi/Defguard_${env:VERSION}_x64_en-US.msi" ` + # "s3://${env:S3_BUCKET}/${env:S3_PREFIX}/${env:BRANCH}/defguard-client-x64-${env:SHA}.msi" diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml new file mode 100644 index 000000000..d4b46d3da --- /dev/null +++ b/.github/workflows/nightly.yaml @@ -0,0 +1,102 @@ +name: "Nightly builds" +on: + schedule: + - cron: "0 23 * * *" + workflow_dispatch: + +env: + S3_BUCKET: nightly.defguard.net + S3_PREFIX: defguard-client + AWS_DEFAULT_REGION: eu-central-1 + +jobs: + release-2-1: + uses: ./.github/workflows/nightly-build-2x.yaml + with: + branch: release/2.1 + s3_bucket: nightly.defguard.net + s3_prefix: defguard-client + aws_region: eu-central-1 + secrets: inherit + + dev: + needs: release-2-1 + if: always() + uses: ./.github/workflows/nightly-build-2x.yaml + with: + branch: dev + s3_bucket: nightly.defguard.net + s3_prefix: defguard-client + aws_region: eu-central-1 + secrets: inherit + + main: + needs: dev + if: always() + uses: ./.github/workflows/nightly-build-1x.yaml + with: + branch: main + s3_bucket: nightly.defguard.net + s3_prefix: defguard-client + aws_region: eu-central-1 + secrets: inherit + + update-index: + needs: + - release-2-1 + - dev + - main + if: always() + runs-on: + - self-hosted + - Linux + - X64 + steps: + - name: Install awscli + run: | + sudo apt-get update + sudo apt-get install -y awscli jq + + - name: Generate and upload index.html + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_NIGHTLY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY_NIGHTLY }} + VERSION_RELEASE_2_1: ${{ needs.release-2-1.outputs.version }} + VERSION_DEV: ${{ needs.dev.outputs.version }} + VERSION_MAIN: ${{ needs.main.outputs.version }} + run: | + jq -n \ + --arg release_2_1 "${VERSION_RELEASE_2_1:-unknown}" \ + --arg dev "${VERSION_DEV:-unknown}" \ + --arg main "${VERSION_MAIN:-unknown}" \ + '{"release-2.1": $release_2_1, "dev": $dev, "main": $main}' > versions.json + + aws s3api list-objects-v2 \ + --bucket "${S3_BUCKET}" \ + --prefix "${S3_PREFIX}/" \ + --query 'Contents[?Size > `0`].{key: Key, size: Size, modified: LastModified}' \ + --output json > objects.json + + { + echo '' + echo '' + echo 'defguard-client nightly builds' + echo '' + echo '

defguard-client nightly builds

' + jq -r --slurpfile versions versions.json ' + (. // []) + | group_by(.key | split("/")[1]) + | map(sort_by(.modified) | reverse) + | sort_by(.[0].modified) | reverse + | .[] + | (.[0].key | split("/")[1]) as $directory + | ($versions[0][$directory] // "unknown") as $version + | "

\($directory) (\($version))

", + "", + (.[] | ""), + "
FileSizeUploaded on (UTC)
\(.key | split("/")[2])\((.size / 104857.6 | round) / 10) MiB\(.modified[0:10]) \(.modified[11:16])
" + ' objects.json + } > index.html + cat index.html + aws s3 cp --acl public-read --content-type text/html \ + index.html "s3://${S3_BUCKET}/index.html" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c9d5c7f55..efe682701 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -148,6 +148,11 @@ jobs: asset_content_type: application/octet-stream build-linux: + env: + CARGO_TERM_COLOR: always + # sccache + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" needs: - create-release outputs: @@ -215,6 +220,9 @@ jobs: - name: Install Rust stable uses: dtolnay/rust-toolchain@stable + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.10 + - name: Install tauri-cli run: cargo install tauri-cli --locked diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml index c0279f2cc..ab36a4314 100644 --- a/.github/workflows/sbom.yml +++ b/.github/workflows/sbom.yml @@ -29,8 +29,15 @@ jobs: - name: Checkout uses: actions/checkout@v7 with: + ref: ${{ steps.vars.outputs.TAG_NAME }} submodules: recursive + - name: Use current vulnerability policy from default branch + if: inputs.tag != '' + run: | + git fetch --depth=1 origin ${{ github.event.repository.default_branch }} + git checkout FETCH_HEAD -- .trivyignore.yaml || echo "Keeping tagged .trivyignore.yaml" + - name: Create SBOM with Trivy uses: aquasecurity/trivy-action@v0.36.0 env: diff --git a/.github/workflows/update-chocolatey.yml b/.github/workflows/update-chocolatey.yml new file mode 100644 index 000000000..efeb7f711 --- /dev/null +++ b/.github/workflows/update-chocolatey.yml @@ -0,0 +1,77 @@ +name: Update Chocolatey package + +on: + release: + types: [published] + +jobs: + update-chocolatey: + if: github.event.release.prerelease == false + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set release version + shell: pwsh + run: | + $version = "${{ github.event.release.tag_name }}".TrimStart('v').Split('-')[0] + "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Set MSI variables + shell: pwsh + run: | + $msiName = "Defguard_${env:VERSION}_x64_en-US.msi" + $msiUrl = "https://github.com/DefGuard/client/releases/download/v${env:VERSION}/Defguard_${env:VERSION}_x64_en-US.msi" + "MSI_NAME=$msiName" | Out-File -FilePath $env:GITHUB_ENV -Append + "MSI_URL=$msiUrl" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Download MSI asset + shell: pwsh + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release download "${{ github.event.release.tag_name }}" --pattern $env:MSI_NAME --dir "$pwd" + + - name: Calculate MSI checksum + shell: pwsh + run: | + $hash = (Get-FileHash -Algorithm SHA256 -Path $env:MSI_NAME).Hash.ToLower() + "MSI_SHA256=$hash" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Update Chocolatey package files + shell: pwsh + working-directory: chocolatey/defguard + run: | + $nuspecPath = "defguard.nuspec" + $installPath = "tools\chocolateyinstall.ps1" + + (Get-Content -Raw $nuspecPath) ` + -replace '[^<]+', "$env:VERSION" | + Set-Content -NoNewline -Encoding UTF8 $nuspecPath + + $content = Get-Content -Raw $installPath + $content = $content -replace '__MSI_URL__', $env:MSI_URL + $content = $content -replace '__MSI_CHECKSUM__', $env:MSI_SHA256 + $content | Set-Content -NoNewline -Encoding UTF8 $installPath + + - name: Refresh local nupkg + shell: pwsh + working-directory: chocolatey/defguard + run: | + $old = Get-ChildItem -Filter "defguard.*.nupkg" | Where-Object { $_.Name -ne "defguard.$env:VERSION.nupkg" } + if ($old) { $old | Remove-Item -Force } + + - name: Pack Chocolatey package + shell: pwsh + working-directory: chocolatey/defguard + run: choco pack + + - name: Push Chocolatey package + shell: pwsh + working-directory: chocolatey/defguard + env: + CHOCO_API_KEY: ${{ secrets.CHOCO_API_KEY }} + run: | + $nupkg = "defguard.$env:VERSION.nupkg" + choco push $nupkg --source "https://push.chocolatey.org/" -k="$env:CHOCO_API_KEY" diff --git a/.gitignore b/.gitignore index 95eef0d0f..9688945cc 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ dist-ssr *.db *.db-shm *.db-wal +*.provisionprofile src-tauri/gen/ diff --git a/chocolatey/defguard/README.md b/chocolatey/defguard/README.md new file mode 100644 index 000000000..a09694c43 --- /dev/null +++ b/chocolatey/defguard/README.md @@ -0,0 +1,27 @@ +# Defguard Chocolatey package + +This directory contains the Chocolatey package source for Defguard. +The GitHub Actions workflow updates version, MSI URL, and checksum after a release is published. + +## Workflow behavior + +- Trigger: GitHub release `published` (non-prerelease). +- Source MSI: Release asset named `Defguard__x64_en-US.msi`. +- Updated files: + - `defguard.nuspec` (``, ``) + - `tools/chocolateyinstall.ps1` (`$url`, `checksum`) +- Package build: `choco pack`. +- Package push: `choco push` to `https://push.chocolatey.org/`. + +## Required secret + +- `CHOCO_API_KEY` in GitHub repo secrets. + +## Local testing (Windows) + +From this directory: + +``` +choco pack +choco install defguard --source . +``` diff --git a/chocolatey/defguard/defguard.nuspec b/chocolatey/defguard/defguard.nuspec new file mode 100755 index 000000000..77810efe3 --- /dev/null +++ b/chocolatey/defguard/defguard.nuspec @@ -0,0 +1,24 @@ + + + + defguard + 1.6.10 + Defguard + Defguard + https://defguard.net + http://rawcdn.githack.com/defguard/client/main/src/shared/images/png/logo_256-256.png + Copyright 2026 Defguard Sp. z o.o. + https://github.com/DefGuard/client/blob/main/LICENSE.md + true + https://github.com/DefGuard/client + https://docs.defguard.net/ + https://github.com/DefGuard/client/issues + defguard vpn wireguard sso mfa + Desktop client for Defguard - Wireguard VPN with MFA + Desktop client provides an easy way to access VPN locations of multiple Defguard instances via user-friendly UI. + https://github.com/DefGuard/client/releases + + + + + diff --git a/chocolatey/defguard/tools/chocolateyinstall.ps1 b/chocolatey/defguard/tools/chocolateyinstall.ps1 new file mode 100755 index 000000000..0593be300 --- /dev/null +++ b/chocolatey/defguard/tools/chocolateyinstall.ps1 @@ -0,0 +1,23 @@ +$ErrorActionPreference = 'Stop' +$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)" +$url = '__MSI_URL__' +$checksum = '__MSI_CHECKSUM__' + +$packageArgs = @{ + packageName = $env:ChocolateyPackageName + unzipLocation = $toolsDir + fileType = 'msi' + url = $url + + softwareName = 'defguard*' + + checksum = $checksum + checksumType = 'sha256' + + silentArgs = "/qn /norestart /l*v `"$($env:TEMP)\$($packageName).$($env:chocolateyPackageVersion).MsiInstall.log`"" + validExitCodes= @(0, 3010, 1641) +} + +Install-ChocolateyPackage @packageArgs +Write-Warning "IMPORTANT: Reboot or Re-login Required: On initial install the user is added to the defguard group.A reboot or logging out and back in is required for group membership changes to take effect. This is not required on subsequent updates." + \ No newline at end of file diff --git a/chocolatey/defguard/tools/chocolateyuninstall.ps1 b/chocolatey/defguard/tools/chocolateyuninstall.ps1 new file mode 100755 index 000000000..cc8b69e8c --- /dev/null +++ b/chocolatey/defguard/tools/chocolateyuninstall.ps1 @@ -0,0 +1,32 @@ +$ErrorActionPreference = 'Stop' +$packageArgs = @{ + packageName = $env:ChocolateyPackageName + softwareName = 'defguard*' + fileType = 'msi' + silentArgs = "/qn /norestart" + validExitCodes= @(0, 3010, 1605, 1614, 1641) +} + +[array]$key = Get-UninstallRegistryKey -SoftwareName $packageArgs['softwareName'] + +if ($key.Count -eq 1) { + $key | % { + $packageArgs['file'] = "$($_.UninstallString)" + + if ($packageArgs['fileType'] -eq 'MSI') { + $packageArgs['silentArgs'] = "$($_.PSChildName) $($packageArgs['silentArgs'])" + + $packageArgs['file'] = '' + } else { + } + + Uninstall-ChocolateyPackage @packageArgs + } +} elseif ($key.Count -eq 0) { + Write-Warning "$packageName has already been uninstalled by other means." +} elseif ($key.Count -gt 1) { + Write-Warning "$($key.Count) matches found!" + Write-Warning "To prevent accidental data loss, no programs will be uninstalled." + Write-Warning "Please alert package maintainer the following keys were matched:" + $key | % {Write-Warning "- $($_.DisplayName)"} +}