Prepare for pub.dev publishing with Gitea release pipeline
- Add README.md and CHANGELOG.md (required by pub.dev) - Add .pubignore / ios/.pubignore to include xcframework in published package - Add Gitea Actions workflow: builds xcframework and publishes on release - Release tag must match pubspec version with no v prefix (e.g. "0.1.0") - Requires PUB_TOKEN secret in Gitea repo settings Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
63f0315ee7
commit
0f42ada793
60
.gitea/workflows/publish.yml
Normal file
60
.gitea/workflows/publish.yml
Normal file
@ -0,0 +1,60 @@
|
||||
name: Publish to pub.dev
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Validate release tag (no v prefix)
|
||||
run: |
|
||||
TAG="${{ gitea.event.release.tag_name }}"
|
||||
if [[ "$TAG" == v* ]]; then
|
||||
echo "Error: tag '$TAG' has a v prefix. Use '0.1.0' not 'v0.1.0'"
|
||||
exit 1
|
||||
fi
|
||||
echo "Publishing version: $TAG"
|
||||
|
||||
- name: Verify version matches pubspec
|
||||
run: |
|
||||
TAG="${{ gitea.event.release.tag_name }}"
|
||||
PUBSPEC_VERSION=$(grep '^version:' pubspec.yaml | awk '{print $2}')
|
||||
if [ "$TAG" != "$PUBSPEC_VERSION" ]; then
|
||||
echo "Error: tag '$TAG' doesn't match pubspec version '$PUBSPEC_VERSION'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Install Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: stable
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
|
||||
- name: Install Xcode tools
|
||||
run: xcode-select --install 2>/dev/null || true
|
||||
|
||||
- name: Build xcframework from Go source
|
||||
run: |
|
||||
chmod +x build_go.sh
|
||||
./build_go.sh
|
||||
|
||||
- name: Verify xcframework exists
|
||||
run: |
|
||||
ls -lh ios/TailscaleKit.xcframework/ios-arm64/TailscaleKit.framework/TailscaleKit
|
||||
ls -lh ios/TailscaleKit.xcframework/ios-arm64-simulator/TailscaleKit.framework/TailscaleKit
|
||||
|
||||
- name: Dry run publish
|
||||
run: dart pub publish --dry-run
|
||||
|
||||
- name: Publish to pub.dev
|
||||
run: dart pub publish --force
|
||||
env:
|
||||
PUB_TOKEN: ${{ secrets.PUB_TOKEN }}
|
||||
19
.pubignore
Normal file
19
.pubignore
Normal file
@ -0,0 +1,19 @@
|
||||
# Git-specific
|
||||
.git/
|
||||
.gitignore
|
||||
|
||||
# Build artifacts (but NOT TailscaleKit.xcframework — that ships with the package)
|
||||
.dart_tool/
|
||||
.packages
|
||||
.pub/
|
||||
build/
|
||||
|
||||
# Go source and build tools (users don't need these)
|
||||
ios/Go/
|
||||
ios/_current_slice
|
||||
ios/.gitignore
|
||||
build_go.sh
|
||||
test/
|
||||
|
||||
# Override ios/.gitignore — the xcframework MUST ship with the package
|
||||
!ios/TailscaleKit.xcframework/
|
||||
9
CHANGELOG.md
Normal file
9
CHANGELOG.md
Normal file
@ -0,0 +1,9 @@
|
||||
## 0.1.0
|
||||
|
||||
- Initial release
|
||||
- iOS support (arm64 device + simulator)
|
||||
- `start()` / `stop()` — join/leave a Tailnet with an auth key
|
||||
- `startProxy()` / `stopProxy()` — localhost TCP proxy through WireGuard tunnel
|
||||
- `status()` / `tailscaleIP()` — query Tailscale connection state
|
||||
- Built with `go build -buildmode=c-archive` (production Go approach)
|
||||
- No VPN entitlement required — uses userspace netstack
|
||||
61
README.md
Normal file
61
README.md
Normal file
@ -0,0 +1,61 @@
|
||||
# tsnet_flutter
|
||||
|
||||
Embed [Tailscale's tsnet](https://pkg.go.dev/tailscale.com/tsnet) in Flutter apps. Provides a userspace WireGuard tunnel with a localhost TCP proxy — **no VPN entitlement needed** on iOS.
|
||||
|
||||
## How it works
|
||||
|
||||
```
|
||||
Flutter (Dart) → MethodChannel → Swift Plugin → Go static library (tsnet)
|
||||
↓
|
||||
WireGuard tunnel (userspace)
|
||||
↓
|
||||
Remote device (100.x.x.x)
|
||||
```
|
||||
|
||||
The Go layer runs a local TCP proxy: your app connects to `localhost:PORT`, and traffic is forwarded through a WireGuard tunnel to the target device's Tailscale IP. Flutter doesn't know about Tailscale — it just sees a localhost port.
|
||||
|
||||
## Usage
|
||||
|
||||
```dart
|
||||
import 'package:tsnet_flutter/tsnet_flutter.dart';
|
||||
|
||||
final tsnet = TsnetFlutter();
|
||||
|
||||
// Join the Tailnet
|
||||
await tsnet.start(authKey: 'tskey-auth-...');
|
||||
|
||||
// Create a local proxy to the remote device
|
||||
final localPort = await tsnet.startProxy('100.64.0.5', port: 5050);
|
||||
|
||||
// Connect your client to the proxy
|
||||
yourClient.connect('127.0.0.1', port: localPort);
|
||||
|
||||
// Clean up
|
||||
await tsnet.stopProxy();
|
||||
await tsnet.stop();
|
||||
```
|
||||
|
||||
## Platform support
|
||||
|
||||
| Platform | Status |
|
||||
|----------|--------|
|
||||
| iOS | Supported (arm64 device + simulator) |
|
||||
| Android | Planned |
|
||||
|
||||
## Requirements
|
||||
|
||||
- iOS 14.0+
|
||||
- Tailscale auth key (generate at [login.tailscale.com](https://login.tailscale.com/admin/settings/keys))
|
||||
|
||||
## Building from source
|
||||
|
||||
The pre-built xcframework is included in the package. To rebuild from Go source:
|
||||
|
||||
```bash
|
||||
# Prerequisites: Go 1.23+, Xcode
|
||||
./build_go.sh
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
BSD-3-Clause. See [LICENSE](LICENSE).
|
||||
3
ios/.pubignore
Normal file
3
ios/.pubignore
Normal file
@ -0,0 +1,3 @@
|
||||
# Only ignore the build symlink — the xcframework ships with the package
|
||||
_current_slice
|
||||
Go/
|
||||
Loading…
Reference in New Issue
Block a user