From 45aa2d924e854149758d87426b32f5e0787d2ea1 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sun, 14 Jun 2026 21:41:40 +0200 Subject: [PATCH] =?UTF-8?q?ci:=20GitHub=20Actions=20=E2=80=94=20Windows=20?= =?UTF-8?q?tests=20+=20version-tagged=20release=20builds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - windows.yml: flutter analyze + the ConPTY/pty suite on windows-latest (the first real execution of lib/src/pty/windows_pty.dart). Keep out of required checks until reliably green (after T-424); uploads artifacts. - release.yml: on a pubspec.yaml version bump on main, build Linux + Windows bundles via `make build` and publish a v GitHub Release. First cut — Windows has never been built, so expect to iterate from the first run's logs. GitHub is the primary remote and the only host with Windows runners; the Gitea secondary has Actions disabled. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/release.yml | 89 +++++++++++++++++++++++++++++++++++ .github/workflows/windows.yml | 43 +++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..ab4d7a23 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,89 @@ +name: release + +# Build + publish versioned Windows and Linux release bundles when the version +# in pubspec.yaml changes on main. The `version` job only proceeds when the +# v tag doesn't already exist, so an unrelated pubspec edit is a no-op. +# +# FIRST CUT — neither build has run in CI yet (Windows has never been built at +# all), so expect to iterate on these from the first run's logs. The repo's own +# `make` targets are the build contract (gen-build-info + clide-cli + flutter +# build, all wired in `make build`). + +on: + push: + branches: [main] + paths: ['pubspec.yaml'] + workflow_dispatch: + +permissions: + contents: write # create the tag + the release + +jobs: + version: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.v.outputs.version }} + fresh: ${{ steps.v.outputs.fresh }} + steps: + - uses: actions/checkout@v4 + with: { fetch-depth: 0 } # tags, to tell new vs. already-released + - id: v + shell: bash + run: | + version=$(awk -F': *' '/^version:/ {gsub(/[" ]/,"",$2); print $2; exit}' pubspec.yaml) + echo "version=$version" >> "$GITHUB_OUTPUT" + if git rev-parse "v$version" >/dev/null 2>&1; then + echo "fresh=false" >> "$GITHUB_OUTPUT" + echo "v$version already tagged — nothing to release." + else + echo "fresh=true" >> "$GITHUB_OUTPUT" + echo "v$version is new — building." + fi + + build-linux: + needs: version + if: needs.version.outputs.fresh == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@v2 + with: { channel: stable } + - run: sudo apt-get update && sudo apt-get install -y ninja-build libgtk-3-dev + - run: make dugite-fetch + - run: make build # gen-build-info + clide-cli + flutter build linux + - name: package + run: tar -C build/linux/x64/release/bundle -czf clide-linux-x64-${{ needs.version.outputs.version }}.tar.gz . + - uses: actions/upload-artifact@v4 + with: { name: linux, path: clide-linux-x64-*.tar.gz } + + build-windows: + needs: version + if: needs.version.outputs.fresh == 'true' + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@v2 + with: { channel: stable } + - run: choco install -y make + - name: build + shell: bash + run: make dugite-fetch && make build # MSVC + bash already on windows-latest + - name: package + shell: pwsh + run: Compress-Archive -Path build/windows/x64/runner/Release/* -DestinationPath clide-windows-x64-${{ needs.version.outputs.version }}.zip + - uses: actions/upload-artifact@v4 + with: { name: windows, path: clide-windows-x64-*.zip } + + publish: + needs: [version, build-linux, build-windows] + if: needs.version.outputs.fresh == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v4 + with: { path: dist } + - uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ needs.version.outputs.version }} + name: clide v${{ needs.version.outputs.version }} + files: dist/**/* + generate_release_notes: true diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 00000000..3d80aac3 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,43 @@ +name: windows + +# Windows CI on GitHub-hosted runners — the only hosted Windows available, and +# GitHub is clide's primary remote (the Gitea secondary is self-hosted Linux and +# keeps running the Linux suite). This is the first real execution of the ConPTY +# backend (lib/src/pty/windows_pty.dart), so expect genuine failures until the +# Windows fixes land (T-424). Keep this OUT of required status checks until it's +# reliably green — it reports + uploads artifacts without blocking merges. Each +# run is a fresh, discarded runner, so the accumulation freeze (which needs +# repeated runs on one machine) can't build up here. + +on: + push: + branches: [main, windows-support] + pull_request: + workflow_dispatch: + +jobs: + windows-pty: + runs-on: windows-latest + timeout-minutes: 25 + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - run: flutter --version + - run: flutter pub get + - run: flutter analyze + - name: ConPTY + Windows-arg unit tests + # windows_pty_test.dart drives real ConPTY (it self-skips off-Windows); + # the args/size suites are the pure-logic coverage. --timeout 60s so a + # wedged reader fails fast instead of hanging the runner. + run: dart test --concurrency=1 --timeout 60s test/pty/windows_pty_test.dart test/pty/windows_pty_args_test.dart test/pty/pty_size_test.dart + - name: Upload test output / logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: windows-test-output + # T-425 (crash-survivable FileLogSink) writes under %LOCALAPPDATA%\clide\logs; + # add that path here once it lands so a freeze leaves a downloadable log. + path: test/.test-output + if-no-files-found: ignore