From 754780a5da7df56b63ffee926cd9c1354c0312ce Mon Sep 17 00:00:00 2001 From: t1k <154753100+t1ktakdev@users.noreply.github.com> Date: Sun, 13 Sep 2026 18:31:13 +0600 Subject: [PATCH] chore: harden repository release workflow --- .github/ISSUE_TEMPLATE/config.yml | 6 ++ .github/dependabot.yml | 44 ++++++++++ .github/release.yml | 22 +++++ .github/workflows/release.yml | 129 ++++++++++++++++++++++++++++++ 4 files changed, 201 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/release.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..a4be086 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +blank_issues_enabled: false + +contact_links: + - name: Security reports + url: https://github.com/t1ktakdev/ReproDeck/blob/main/SECURITY.md + about: Please follow the private reporting instructions in SECURITY.md. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..33f3380 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,44 @@ +version: 2 + +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + day: monday + time: "07:00" + timezone: Asia/Bishkek + open-pull-requests-limit: 5 + groups: + npm-non-major: + update-types: + - minor + - patch + + - package-ecosystem: cargo + directory: / + schedule: + interval: weekly + day: monday + time: "07:15" + timezone: Asia/Bishkek + open-pull-requests-limit: 5 + groups: + cargo-non-major: + update-types: + - minor + - patch + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + time: "07:30" + timezone: Asia/Bishkek + open-pull-requests-limit: 3 + groups: + actions-non-major: + update-types: + - minor + - patch diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..5eb88ef --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,22 @@ +changelog: + exclude: + labels: + - skip-changelog + - dependencies + authors: + - dependabot[bot] + + categories: + - title: Features + labels: + - enhancement + - feature + + - title: Fixes + labels: + - bug + - fix + + - title: Maintenance + labels: + - "*" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..da1f6e7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,129 @@ +name: Release + +on: + push: + tags: + - "v*.*.*" + +permissions: + contents: write + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +jobs: + windows: + name: Windows x64 + runs-on: windows-latest + + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-node@v7 + with: + node-version: 22 + cache: npm + + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - uses: Swatinem/rust-cache@v2 + + - name: Verify release version + shell: pwsh + run: | + $tag = "${{ github.ref_name }}" + if (-not $tag.StartsWith("v")) { + throw "Release tags must start with v" + } + + $version = $tag.Substring(1) + $packageVersion = (Get-Content package.json -Raw | ConvertFrom-Json).version + $tauriVersion = (Get-Content src-tauri/tauri.conf.json -Raw | ConvertFrom-Json).version + $cargoText = Get-Content Cargo.toml -Raw + $cargoMatch = [regex]::Match( + $cargoText, + '(?ms)^\[workspace\.package\].*?^version\s*=\s*"([^"]+)"' + ) + + if (-not $cargoMatch.Success) { + throw "Could not read workspace.package.version from Cargo.toml" + } + + $cargoVersion = $cargoMatch.Groups[1].Value + $versions = @{ + "package.json" = $packageVersion + "src-tauri/tauri.conf.json" = $tauriVersion + "Cargo.toml" = $cargoVersion + } + + foreach ($entry in $versions.GetEnumerator()) { + if ($entry.Value -ne $version) { + throw "$($entry.Key) has version $($entry.Value), expected $version from tag $tag" + } + } + + "RELEASE_VERSION=$version" >> $env:GITHUB_ENV + + - name: Install frontend dependencies + run: npm ci --no-audit + + - name: Rust format + run: cargo fmt --all -- --check + + - name: Rust check + run: cargo check --workspace --all-targets + + - name: Rust clippy + run: cargo clippy --workspace --all-targets -- -D warnings + + - name: Rust tests + run: cargo test --workspace --all-targets + + - name: Frontend typecheck + run: npm run typecheck + + - name: Frontend tests + run: npm test + + - name: Frontend build + run: npm run build + + - name: Build NSIS installer + run: npm run release:windows + + - name: Prepare release assets + shell: pwsh + run: | + $installer = Get-ChildItem "target/release/bundle/nsis" -Filter "*.exe" | + Select-Object -First 1 + + if (-not $installer) { + throw "Tauri did not produce an NSIS installer" + } + + New-Item -ItemType Directory -Force -Path dist-release | Out-Null + $assetName = "ReproDeck_$env:RELEASE_VERSION`_x64-setup.exe" + $assetPath = Join-Path "dist-release" $assetName + Copy-Item $installer.FullName $assetPath + + $hash = (Get-FileHash $assetPath -Algorithm SHA256).Hash.ToLowerInvariant() + "$hash $assetName" | Set-Content -Encoding ascii "dist-release/SHA256SUMS.txt" + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: ReproDeck-${{ env.RELEASE_VERSION }}-windows-x64 + path: dist-release/* + if-no-files-found: error + retention-days: 14 + + - name: Publish GitHub release + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true + files: | + dist-release/*.exe + dist-release/SHA256SUMS.txt