Scaffold ipswap: tray-driven Windows IP preset switcher
Implements the design in claude.md as a building skeleton: pure Go, no cgo, cross-compiles to a single Windows .exe from Linux. Architecture follows the spec's deliberate split. The fast path is native — tray icon, grouped submenus, a Win32 MessageBox showing a live before/after diff, then netsh. The slow path is an embedded web editor served on a random loopback port and opened in the default browser. Two decisions worth recording: Reads use GetAdaptersAddresses, writes use netsh. The spec left the enumeration mechanism open; parsing `netsh show config` breaks on a non-English Windows because the output is localised. DNS static-vs-DHCP origin is not exposed by that API, so it comes from one registry read. The netsh command plan is built in portable code. That puts the delete-every- existing-address step — the one that stops secondary addresses leaking across switches — under test without needing a Windows box. The editor requires the session token in a header for mutations, not just the cookie: any page in the browser can make it POST to 127.0.0.1 with the cookie attached, but it cannot set a header. The updater refuses to install a release that publishes no SHA256. Not yet done: no group picker for export (the API supports it), no single-instance guard, and internal/server/web/app.css is reconstructed from the description in claude.md rather than the canonical apointless.css. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# Builds ipswap.exe on every tag and attaches it, with its checksum, to the
|
||||
# Gitea release.
|
||||
#
|
||||
# There is no Wine step and no mingw step: ipswap is pure Go with no cgo, so a
|
||||
# Linux runner cross-compiles the Windows binary directly. That constraint is
|
||||
# why the tray is fyne.io/systray and the dialogs are raw user32 calls — keep
|
||||
# it that way and this file stays this short.
|
||||
#
|
||||
# The SHA256SUMS artifact is not decoration. The in-app updater refuses to
|
||||
# install a release that publishes no checksum, so a release built without this
|
||||
# step cannot be auto-updated to.
|
||||
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.26"
|
||||
cache: true
|
||||
|
||||
- name: Derive version from the tag
|
||||
id: version
|
||||
run: echo "version=${GITEA_REF_NAME#v}" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GITEA_REF_NAME: ${{ gitea.ref_name }}
|
||||
|
||||
- name: Test
|
||||
run: go test ./...
|
||||
|
||||
- name: Vet both targets
|
||||
run: |
|
||||
go vet ./...
|
||||
GOOS=windows GOARCH=amd64 go vet ./...
|
||||
|
||||
- name: Build
|
||||
run: make dist VERSION=${{ steps.version.outputs.version }}
|
||||
|
||||
- name: Publish the release
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
files: |
|
||||
dist/ipswap.exe
|
||||
dist/SHA256SUMS
|
||||
body: |
|
||||
ipswap v${{ steps.version.outputs.version }}
|
||||
|
||||
SHA256 of `ipswap.exe` is published in the `SHA256SUMS` asset;
|
||||
the in-app updater verifies against it before installing.
|
||||
Reference in New Issue
Block a user