feat: security hardening, production roadmap, admin panel v1
checklocks / checklocks (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
natlab-integrationtest / natlab-integrationtest (push) Has been cancelled
CI / gomod-cache (push) Has been cancelled
CI / race-root-integration (1/4) (push) Has been cancelled
CI / race-root-integration (2/4) (push) Has been cancelled
CI / race-root-integration (3/4) (push) Has been cancelled
CI / race-root-integration (4/4) (push) Has been cancelled
CI / test (-race, amd64, 1/3) (push) Has been cancelled
CI / test (-race, amd64, 2/3) (push) Has been cancelled
CI / test (-race, amd64, 3/3) (push) Has been cancelled
CI / test (386) (push) Has been cancelled
CI / test (amd64) (push) Has been cancelled
CI / Windows (benchmarks) (push) Has been cancelled
CI / Windows (1/2) (push) Has been cancelled
CI / Windows (2/2) (push) Has been cancelled
CI / macos (push) Has been cancelled
CI / privileged (push) Has been cancelled
CI / vm (push) Has been cancelled
CI / cross (386, linux) (push) Has been cancelled
CI / cross (amd64, darwin) (push) Has been cancelled
CI / cross (amd64, freebsd) (push) Has been cancelled
CI / cross (amd64, openbsd) (push) Has been cancelled
CI / cross (amd64, windows) (push) Has been cancelled
CI / cross (arm, 5, linux) (push) Has been cancelled
CI / cross (arm, 7, linux) (push) Has been cancelled
CI / cross (arm64, darwin) (push) Has been cancelled
CI / cross (arm64, linux) (push) Has been cancelled
CI / cross (arm64, windows) (push) Has been cancelled
CI / cross (loong64, linux) (push) Has been cancelled
CI / ios (push) Has been cancelled
CI / crossmin (amd64, illumos) (push) Has been cancelled
CI / crossmin (amd64, plan9) (push) Has been cancelled
CI / crossmin (amd64, solaris) (push) Has been cancelled
CI / crossmin (ppc64, aix) (push) Has been cancelled
CI / android (push) Has been cancelled
CI / wasm (push) Has been cancelled
CI / tailscale_go (push) Has been cancelled
CI / fuzz (push) Has been cancelled
CI / depaware (push) Has been cancelled
CI / go_generate (push) Has been cancelled
CI / make_tidy (push) Has been cancelled
CI / licenses (push) Has been cancelled
CI / staticcheck (macOS) (push) Has been cancelled
CI / staticcheck (Linux) (push) Has been cancelled
CI / staticcheck (Windows) (push) Has been cancelled
CI / staticcheck (Portable (1/4)) (push) Has been cancelled
CI / staticcheck (Portable (2/4)) (push) Has been cancelled
CI / staticcheck (Portable (3/4)) (push) Has been cancelled
CI / staticcheck (Portable (4/4)) (push) Has been cancelled
CI / notify_slack (push) Has been cancelled
CI / merge_blocker (push) Has been cancelled
CI / check_mergeability_strict (push) Has been cancelled
CI / check_mergeability (push) Has been cancelled
Dockerfile build / deploy (push) Has been cancelled
test installer.sh / test (curl, alpine:3.21) (push) Has been cancelled
test installer.sh / test (curl, alpine:edge) (push) Has been cancelled
test installer.sh / test (curl, alpine:latest) (push) Has been cancelled
test installer.sh / test (curl, amazonlinux:latest) (push) Has been cancelled
test installer.sh / test (curl, archlinux:latest) (push) Has been cancelled
test installer.sh / test (curl, debian:oldstable-slim) (push) Has been cancelled
test installer.sh / test (curl, debian:sid-slim) (push) Has been cancelled
test installer.sh / test (curl, debian:stable-slim, 1.80.0) (push) Has been cancelled
test installer.sh / test (curl, debian:testing-slim) (push) Has been cancelled
test installer.sh / test (curl, elementary/docker:stable) (push) Has been cancelled
test installer.sh / test (curl, elementary/docker:unstable) (push) Has been cancelled
test installer.sh / test (curl, fedora:latest, 1.80.0) (push) Has been cancelled
test installer.sh / test (curl, kalilinux/kali-dev) (push) Has been cancelled
test installer.sh / test (curl, kalilinux/kali-rolling) (push) Has been cancelled
test installer.sh / test (curl, opensuse/leap:latest) (push) Has been cancelled
test installer.sh / test (curl, opensuse/tumbleweed:latest) (push) Has been cancelled
test installer.sh / test (curl, oraclelinux:8) (push) Has been cancelled
test installer.sh / test (curl, oraclelinux:9) (push) Has been cancelled
test installer.sh / test (curl, parrotsec/core:latest) (push) Has been cancelled
test installer.sh / test (curl, rockylinux:8.7) (push) Has been cancelled
test installer.sh / test (curl, rockylinux:9) (push) Has been cancelled
test installer.sh / test (curl, ubuntu:20.04) (push) Has been cancelled
test installer.sh / test (curl, ubuntu:22.04) (push) Has been cancelled
test installer.sh / test (curl, ubuntu:24.04, 1.80.0) (push) Has been cancelled
test installer.sh / test (wget, debian:oldstable-slim) (push) Has been cancelled
test installer.sh / test (wget, debian:sid-slim) (push) Has been cancelled
update-flake / update-flake (push) Has been cancelled
tailscale.com/cmd/vet / vet (push) Has been cancelled
test installer.sh / notify-slack (push) Has been cancelled

Client security fixes (cmd/tailscale-tray/main.go):
- SSRF protection in Add Server dialog (validateControlURL): reject
  private/loopback/link-local/cloud-metadata IPs via DNS resolution
- RCE gate on AuthURL/BrowseToURL exec paths (validateAuthURL)
- Sanitized URL logging (sanitizeURLForLog drops query auth tokens)
- Error handling on exec.Command with user-facing showError()

Admin panel security (web-admin):
- Bcrypt password hashing (replaces SHA256)
- Rate limiting: 5 failed logins → 15-min lockout
- Session + login attempt cleanup goroutine (hourly)
- url.QueryEscape / encodeURIComponent for all API params
- Fail-hard startup when no TLS and non-loopback bind
- ADMIN_PASSWORD required (no default), password min 12 chars
- Username regex whitelist

Installer hardening (Setup.wxs):
- util:PermissionEx restricts SCM access: only Administrators +
  SYSTEM can start/stop/reconfigure service. Authenticated Users
  limited to QueryStatus/QueryConfig/Interrogate
- Vital="yes" on ServiceInstall

Docs & roadmap:
- PRODUCTION_ROADMAP.md: 5-milestone plan (security + features +
  distribution + ops) with granular tasks, effort, done-when
- CLIENT_SECURITY_AUDIT.md, SECURITY_FIXES.md, DEPLOYMENT.md
- AI assistant rules (.cursorrules, .antigravityrules, etc.)

Build & distribution:
- build-msi.ps1, deploy-and-sign.ps1, sign-release.ps1
- redeploy.ps1, tray-deploy.ps1, test-msi.ps1
- installer/msi/ alternative WXS setup
- Restored .github/workflows/ removed in mirror cleanup

.gitignore hardened: *.pfx, *.p12, *.key, *.pem, .env*
This commit is contained in:
2026-04-22 15:18:11 +07:00
parent a7703701b8
commit 2fb067ecbf
280 changed files with 50374 additions and 120 deletions
+170
View File
@@ -0,0 +1,170 @@
# Antigravity Agent Kit — Instructions for GitHub Copilot
> This file teaches Copilot how to use the `.agent/` toolkit installed in this workspace.
---
## What is `.agent/`?
This workspace contains an AI capability expansion toolkit at `.agent/`. It provides:
- **Agents** (`.agent/agents/*.md`) — Specialist AI personas (frontend, backend, security, etc.)
- **Skills** (`.agent/skills/*/SKILL.md`) — Domain-specific knowledge modules
- **Workflows** (`.agent/workflows/*.md`) — Step-by-step procedures triggered by slash commands
**Read `.agent/ARCHITECTURE.md` first** to understand the full system map.
---
## Agent Routing Protocol
Before writing code or making design decisions:
1. **Identify the domain** of the user's request (Frontend, Backend, Security, Database, etc.)
2. **Select the matching agent** from `.agent/agents/`
3. **Read that agent's `.md` file** to understand its rules, persona, and linked skills
4. **Load linked skills** listed in the agent file's frontmatter (`skills:` field)
5. **Apply the agent's rules** when generating your response
### Agent Selection Guide
| Domain | Agent File | Key Skills |
|--------|-----------|------------|
| Web UI/UX | `frontend-specialist.md` | frontend-design, react-best-practices |
| API/Backend | `backend-specialist.md` | api-patterns, nodejs-best-practices |
| Database | `database-architect.md` | database-design |
| Mobile | `mobile-developer.md` | mobile-design |
| Security | `security-auditor.md` | vulnerability-scanner |
| Testing | `test-engineer.md` | testing-patterns, webapp-testing |
| Debugging | `debugger.md` | systematic-debugging |
| Planning | `project-planner.md` | brainstorming, plan-writing |
| Multi-domain | `orchestrator.md` | parallel-agents |
---
## Skill Loading Protocol
Skills are modular knowledge packages. To use a skill:
1. Read `SKILL.md` inside the skill folder (e.g., `.agent/skills/clean-code/SKILL.md`)
2. Only read the sections relevant to the current task (selective reading)
3. If the skill has a `scripts/` folder, those scripts can be executed for validation
### Skill Structure
```
.agent/skills/{skill-name}/
├── SKILL.md # Main instructions (REQUIRED — read this first)
├── scripts/ # Runnable validation scripts (optional)
├── references/ # Templates and docs (optional)
└── assets/ # Images, resources (optional)
```
### Global Mandatory Skill
**`clean-code`** applies to ALL code. Always follow `.agent/skills/clean-code/SKILL.md`.
---
## Workflow Conventions
Workflow files in `.agent/workflows/*.md` are triggered by slash commands (e.g., `/debug`, `/deploy`).
### Special Annotations
When reading workflow files, understand these Antigravity-specific markers:
| Marker | Meaning |
|--------|---------|
| `$ARGUMENTS` | Placeholder for user-provided arguments after the slash command |
| `// turbo` | The NEXT step can be auto-executed without user confirmation |
| `// turbo-all` | ALL subsequent steps in this section can be auto-executed |
### Available Workflows
| Command | File | Purpose |
|---------|------|---------|
| `/brainstorm` | `brainstorm.md` | Socratic discovery |
| `/create` | `create.md` | Create new features |
| `/debug` | `debug.md` | Systematic debugging |
| `/deploy` | `deploy.md` | Production deployment |
| `/enhance` | `enhance.md` | Improve existing code |
| `/ins-develop` | `ins-develop.md` | INS Module development lifecycle |
| `/orchestrate` | `orchestrate.md` | Multi-agent coordination |
| `/plan` | `plan.md` | Task breakdown |
| `/preview` | `preview.md` | Preview changes |
| `/status` | `status.md` | Check project status |
| `/test` | `test.md` | Run tests |
| `/ui-ux-pro-max` | `ui-ux-pro-max.md` | UI design with 50+ styles |
---
## Rules Priority
When rules conflict, apply this priority:
1. **P0** — This instructions file + GEMINI.md rules
2. **P1** — Agent-specific rules (from `.agent/agents/*.md`)
3. **P2** — Skill-specific rules (from `.agent/skills/*/SKILL.md`)
---
## Code Standards
- Follow **clean-code** skill for all code
- Use **English** for code, comments, and variable names
- Respond in the **user's language** for explanations
- Before modifying files, check for dependencies and update all affected files together
---
## Important Paths
```
.agent/
├── ARCHITECTURE.md # System overview — READ THIS FIRST
├── agents/ # 20 specialist agent definitions
├── skills/ # 38 knowledge modules
├── workflows/ # 16 slash command procedures
├── rules/ # IDE-specific instruction files
└── scripts/ # Master validation scripts
```
---
## 🛡️ Auto-Protection Rules (Always Active)
> These rules are always enforced. No configuration needed.
### Forbidden Directories
**NEVER read or explore these directories** — they waste context and provide no useful information:
`node_modules/`, `.git/`, `dist/`, `build/`, `out/`, `bin/`, `obj/`, `packages/`, `.vs/`, `.idea/`, `__pycache__/`, `.next/`, `.nuxt/`, `.turbo/`, `vendor/`, `target/`, `coverage/`
Instead: use `package.json` or `*.csproj` for dependency info. Use `git` commands for version control. Read source files, not build outputs.
### Sensitive Files
**Always ask the user before reading:** `.env`, `.env.*`, `*.key`, `*.pem`, `*.crt`, `*secret*`, `*credential*`, `appsettings.*.json`, `Web.config`, `launchSettings.json`, `*.pfx`, `*.p12`
When approved: never echo passwords or API keys in responses. Replace with `[REDACTED]`.
### Context Efficiency
- Search for specific content before reading entire files
- Don't re-read files already seen in the conversation
- For large files, read focused ranges (50-100 lines) instead of all at once
- Use `package.json` or `*.csproj`/`*.sln` instead of exploring dependency directories
### Naming Conventions
- **C# source files**: `PascalCase` (`UserService.cs`)
- **JS/TS source files**: `kebab-case` (`user-service.ts`)
- **Components**: `PascalCase` (`UserProfile.tsx`, `NavMenu.razor`)
- **Tests (JS)**: `{name}.test.{ext}` | **Tests (C#)**: `{Name}Tests.cs`
- **KEY**: Always match the project's existing naming convention
### Communication Style
Adapt based on user's expertise level. Default: Senior (code-first, minimal explanation). If user asks basic questions, shift to teaching mode. If user gives terse instructions, respond with pure code.
+34
View File
@@ -0,0 +1,34 @@
name: checklocks
on:
push:
branches:
- main
pull_request:
paths:
- '**/*.go'
- '.github/workflows/checklocks.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
checklocks:
runs-on: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Build checklocks
run: ./tool/go build -o /tmp/checklocks gvisor.dev/gvisor/tools/checklocks/cmd/checklocks
- name: Run checklocks vet
# TODO(#12625): add more packages as we add annotations
run: |-
./tool/go vet -vettool=/tmp/checklocks \
./envknob \
./ipn/store/mem \
./net/stun/stuntest \
./net/wsconn \
./proxymap
+73
View File
@@ -0,0 +1,73 @@
name: Build cigocacher
on:
# Released on-demand. The commit will be used as part of the tag, so generally
# prefer to release from main where the commit is stable in linear history.
workflow_dispatch:
jobs:
build:
strategy:
matrix:
GOOS: ["linux", "darwin", "windows"]
GOARCH: ["amd64", "arm64"]
runs-on: ubuntu-24.04
env:
GOOS: "${{ matrix.GOOS }}"
GOARCH: "${{ matrix.GOARCH }}"
CGO_ENABLED: "0"
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Build
run: |
OUT="cigocacher$(./tool/go env GOEXE)"
./tool/go build -o "${OUT}" ./cmd/cigocacher/
tar -zcf cigocacher-${{ matrix.GOOS }}-${{ matrix.GOARCH }}.tar.gz "${OUT}"
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: cigocacher-${{ matrix.GOOS }}-${{ matrix.GOARCH }}
path: cigocacher-${{ matrix.GOOS }}-${{ matrix.GOARCH }}.tar.gz
release:
runs-on: ubuntu-24.04
needs: build
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: 'cigocacher-*'
merge-multiple: true
# This step is a simplified version of actions/create-release and
# actions/upload-release-asset, which are archived and unmaintained.
- name: Create release
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const fs = require('fs');
const path = require('path');
const { data: release } = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: `cmd/cigocacher/${{ github.sha }}`,
name: `cigocacher-${{ github.sha }}`,
draft: false,
prerelease: true,
target_commitish: `${{ github.sha }}`
});
const files = fs.readdirSync('.').filter(f => f.endsWith('.tar.gz'));
for (const file of files) {
await github.rest.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: release.id,
name: file,
data: fs.readFileSync(file)
});
console.log(`Uploaded ${file}`);
}
+83
View File
@@ -0,0 +1,83 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ main, release-branch/* ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
merge_group:
branches: [ main ]
schedule:
- cron: '31 14 * * 5'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Install a more recent Go that understands modern go.mod content.
- name: Install Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version-file: go.mod
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1
+29
View File
@@ -0,0 +1,29 @@
name: "Validate Docker base image"
on:
workflow_dispatch:
pull_request:
paths:
- "Dockerfile.base"
- ".github/workflows/docker-base.yml"
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: "build and test"
run: |
set -e
IMG="test-base:$(head -c 8 /dev/urandom | xxd -p)"
docker build -t "$IMG" -f Dockerfile.base .
iptables_version=$(docker run --rm "$IMG" iptables --version)
if [[ "$iptables_version" != *"(legacy)"* ]]; then
echo "ERROR: Docker base image should contain legacy iptables; found ${iptables_version}"
exit 1
fi
ip6tables_version=$(docker run --rm "$IMG" ip6tables --version)
if [[ "$ip6tables_version" != *"(legacy)"* ]]; then
echo "ERROR: Docker base image should contain legacy ip6tables; found ${ip6tables_version}"
exit 1
fi
+13
View File
@@ -0,0 +1,13 @@
name: "Dockerfile build"
on:
push:
branches:
- main
pull_request:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: "Build Docker image"
run: docker build .
@@ -0,0 +1,27 @@
name: update-flakehub
on:
push:
tags:
- "v[0-9]+.*[02468].[0-9]+"
workflow_dispatch:
inputs:
tag:
description: "The existing tag to publish to FlakeHub"
type: "string"
required: true
jobs:
flakehub-publish:
runs-on: "ubuntu-latest"
permissions:
id-token: "write"
contents: "read"
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: "${{ (inputs.tag != null) && format('refs/tags/{0}', inputs.tag) || '' }}"
- uses: DeterminateSystems/nix-installer-action@c5a866b6ab867e88becbed4467b93592bce69f8a # v21
- uses: DeterminateSystems/flakehub-push@71f57208810a5d299fc6545350981de98fdbc860 # v6
with:
visibility: "public"
tag: "${{ inputs.tag }}"
+47
View File
@@ -0,0 +1,47 @@
name: golangci-lint
on:
# For now, only lint pull requests, not the main branches.
pull_request:
paths:
- ".github/workflows/golangci-lint.yml"
- "**.go"
- "go.mod"
- "go.sum"
# TODO(andrew): enable for main branch after an initial waiting period.
#push:
# branches:
# - main
workflow_dispatch:
permissions:
contents: read
pull-requests: read
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version-file: go.mod
cache: true
- name: golangci-lint
uses: golangci/golangci-lint-action@b7bcab6379029e905e3f389a6bf301f1bc220662 # head as of 2026-03-04
with:
version: v2.10.1
# Show only new issues if it's a pull request.
only-new-issues: true
# Loading packages with a cold cache takes a while:
args: --timeout=10m
+51
View File
@@ -0,0 +1,51 @@
name: govulncheck
on:
schedule:
- cron: "0 12 * * *" # 8am EST / 10am PST / 12pm UTC
workflow_dispatch: # allow manual trigger for testing
pull_request:
paths:
- ".github/workflows/govulncheck.yml"
jobs:
source-scan:
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install govulncheck
run: ./tool/go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Scan source code for known vulnerabilities
run: PATH=$PWD/tool/:$PATH "$(./tool/go env GOPATH)/bin/govulncheck" -test ./...
- name: Post to slack
if: failure() && github.event_name == 'schedule'
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
with:
method: chat.postMessage
token: ${{ secrets.GOVULNCHECK_BOT_TOKEN }}
payload: |
{
"channel": "C08FGKZCQTW",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Govulncheck failed in ${{ github.repository }}"
},
"accessory": {
"type": "button",
"text": {
"type": "plain_text",
"text": "View results"
},
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
}
]
}
+143
View File
@@ -0,0 +1,143 @@
name: test installer.sh
on:
schedule:
- cron: '0 15 * * *' # 10am EST (UTC-4/5)
push:
branches:
- "main"
paths:
- scripts/installer.sh
- .github/workflows/installer.yml
pull_request:
paths:
- scripts/installer.sh
- .github/workflows/installer.yml
jobs:
test:
strategy:
# Don't abort the entire matrix if one element fails.
fail-fast: false
# Don't start all of these at once, which could saturate Github workers.
max-parallel: 4
matrix:
image:
# This is a list of Docker images against which we test our installer.
# If you find that some of these no longer exist, please feel free
# to remove them from the list.
# When adding new images, please only use official ones.
- "debian:oldstable-slim"
- "debian:stable-slim"
- "debian:testing-slim"
- "debian:sid-slim"
- "ubuntu:20.04"
- "ubuntu:22.04"
- "ubuntu:24.04"
- "elementary/docker:stable"
- "elementary/docker:unstable"
- "parrotsec/core:latest"
- "kalilinux/kali-rolling"
- "kalilinux/kali-dev"
- "oraclelinux:9"
- "oraclelinux:8"
- "fedora:latest"
- "rockylinux:8.7"
- "rockylinux:9"
- "amazonlinux:latest"
- "opensuse/leap:latest"
- "opensuse/tumbleweed:latest"
- "archlinux:latest"
- "alpine:3.21"
- "alpine:latest"
- "alpine:edge"
deps:
# Run all images installing curl as a dependency.
- curl
include:
# Check a few images with wget rather than curl.
- { image: "debian:oldstable-slim", deps: "wget" }
- { image: "debian:sid-slim", deps: "wget" }
- { image: "debian:stable-slim", deps: "curl" }
- { image: "ubuntu:24.04", deps: "curl" }
- { image: "fedora:latest", deps: "curl" }
# Test TAILSCALE_VERSION pinning on a subset of distros.
# Skip Alpine as community repos don't reliably keep old versions.
- { image: "debian:stable-slim", deps: "curl", version: "1.80.0" }
- { image: "ubuntu:24.04", deps: "curl", version: "1.80.0" }
- { image: "fedora:latest", deps: "curl", version: "1.80.0" }
runs-on: ubuntu-latest
container:
image: ${{ matrix.image }}
options: --user root
steps:
- name: install dependencies (pacman)
# Refresh the package databases to ensure that the tailscale package is
# defined.
run: pacman -Sy
if: contains(matrix.image, 'archlinux')
- name: install dependencies (yum)
# tar and gzip are needed by the actions/checkout below.
run: yum install -y --allowerasing tar gzip ${{ matrix.deps }}
if: |
contains(matrix.image, 'centos') ||
contains(matrix.image, 'oraclelinux') ||
contains(matrix.image, 'fedora') ||
contains(matrix.image, 'amazonlinux')
- name: install dependencies (zypper)
# tar and gzip are needed by the actions/checkout below.
run: zypper --non-interactive install tar gzip ${{ matrix.deps }}
if: contains(matrix.image, 'opensuse')
- name: install dependencies (apt-get)
run: |
apt-get update
apt-get install -y ${{ matrix.deps }}
if: |
contains(matrix.image, 'debian') ||
contains(matrix.image, 'ubuntu') ||
contains(matrix.image, 'elementary') ||
contains(matrix.image, 'parrotsec') ||
contains(matrix.image, 'kalilinux')
- name: checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: run installer
run: scripts/installer.sh
env:
TAILSCALE_VERSION: ${{ matrix.version }}
# Package installation can fail in docker because systemd is not running
# as PID 1, so ignore errors at this step. The real check is the
# `tailscale --version` command below.
continue-on-error: true
- name: check tailscale version
run: |
tailscale --version
if [ -n "${{ matrix.version }}" ]; then
tailscale --version | grep -q "^${{ matrix.version }}" || { echo "Version mismatch!"; exit 1; }
fi
notify-slack:
needs: test
runs-on: ubuntu-latest
steps:
- name: Notify Slack of failure on scheduled runs
if: failure() && github.event_name == 'schedule'
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"attachments": [{
"title": "Tailscale installer test failed",
"title_link": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"text": "One or more OSes in the test matrix failed. See the run for details.",
"fields": [
{
"title": "Ref",
"value": "${{ github.ref_name }}",
"short": true
}
],
"footer": "${{ github.workflow }} on schedule",
"color": "danger"
}]
}
+31
View File
@@ -0,0 +1,31 @@
name: "Kubernetes manifests"
on:
pull_request:
paths:
- 'cmd/k8s-operator/**'
- 'k8s-operator/**'
- '.github/workflows/kubemanifests.yaml'
# Cancel workflow run if there is a newer push to the same PR for which it is
# running
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
testchart:
runs-on: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Build and lint Helm chart
run: |
eval `./tool/go run ./cmd/mkversion`
./tool/helm package --app-version="${VERSION_SHORT}" --version=${VERSION_SHORT} './cmd/k8s-operator/deploy/chart'
./tool/helm lint "tailscale-operator-${VERSION_SHORT}.tgz"
- name: Verify that static manifests are up to date
run: |
make kube-generate-all
echo
echo
git diff --name-only --exit-code || (echo "Generated files for Tailscale Kubernetes operator are out of date. Please run 'make kube-generate-all' and commit the diff."; exit 1)
@@ -0,0 +1,33 @@
# Run some natlab integration tests.
# See https://github.com/tailscale/tailscale/issues/13038
name: "natlab-integrationtest"
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
on:
push:
branches:
- "main"
- "release-branch/*"
pull_request:
# all PRs on all branches
merge_group:
branches:
- "main"
jobs:
natlab-integrationtest:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install qemu
run: |
sudo rm -f /var/lib/man-db/auto-update
sudo apt-get -y update
sudo apt-get -y remove man-db
sudo apt-get install -y qemu-system-x86 qemu-utils
- name: Run natlab integration tests
run: |
./tool/go test -v -run=^TestEasyEasy$ -timeout=3m -count=1 ./tstest/integration/nat --run-vm-tests
+29
View File
@@ -0,0 +1,29 @@
# Pin images used in github actions to a hash instead of a version tag.
name: pin-github-actions
on:
pull_request:
branches:
- main
paths:
- ".github/workflows/**"
workflow_dispatch:
permissions:
contents: read
pull-requests: read
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
run:
name: pin-github-actions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: pin
run: make pin-github-actions
- name: check for changed workflow files
run: git diff --no-ext-diff --exit-code .github/workflows || (echo "Some github actions versions need pinning, run make pin-github-actions."; exit 1)
@@ -0,0 +1,32 @@
name: request-dataplane-review
on:
pull_request:
types: [ opened, synchronize, reopened, ready_for_review ]
paths:
- ".github/workflows/request-dataplane-review.yml"
- "**/*derp*"
- "**/derp*/**"
- "!**/depaware.txt"
jobs:
request-dataplane-review:
if: github.event.pull_request.draft == false
name: Request Dataplane Review
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get access token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
id: generate-token
with:
# Get token for app: https://github.com/apps/change-visibility-bot
app-id: ${{ secrets.VISIBILITY_BOT_APP_ID }}
private-key: ${{ secrets.VISIBILITY_BOT_APP_PRIVATE_KEY }}
- name: Add reviewers
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
url: ${{ github.event.pull_request.html_url }}
run: |
gh pr edit "$url" --add-reviewer tailscale/dataplane
+23
View File
@@ -0,0 +1,23 @@
# Run the ssh integration tests with `make sshintegrationtest`.
# These tests can also be running locally.
name: "ssh-integrationtest"
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
on:
pull_request:
paths:
- "ssh/**"
- "tempfork/gliderlabs/ssh/**"
- ".github/workflows/ssh-integrationtest"
jobs:
ssh-integrationtest:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run SSH integration tests
run: |
make sshintegrationtest
File diff suppressed because it is too large Load Diff
+49
View File
@@ -0,0 +1,49 @@
name: update-flake
on:
# run action when a change lands in the main branch which updates go.mod. Also
# allow manual triggering.
push:
branches:
- main
paths:
- go.mod
- .github/workflows/update-flake.yml
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
update-flake:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run update-flakes
run: ./update-flake.sh
- name: Get access token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
id: generate-token
with:
# Get token for app: https://github.com/apps/tailscale-code-updater
app-id: ${{ secrets.CODE_UPDATER_APP_ID }}
private-key: ${{ secrets.CODE_UPDATER_APP_PRIVATE_KEY }}
- name: Send pull request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 #v8.1.0
with:
token: ${{ steps.generate-token.outputs.token }}
author: Flakes Updater <noreply+flakes-updater@tailscale.com>
committer: Flakes Updater <noreply+flakes-updater@tailscale.com>
branch: flakes
commit-message: "go.mod.sri: update SRI hash for go.mod changes"
title: "go.mod.sri: update SRI hash for go.mod changes"
body: Triggered by ${{ github.repository }}@${{ github.sha }}
signoff: true
delete-branch: true
reviewers: danderson
@@ -0,0 +1,50 @@
name: update-webclient-prebuilt
on:
# manually triggered
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
update-webclient-prebuilt:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run go get
run: |
./tool/go version # build gocross if needed using regular GOPROXY
GOPROXY=direct ./tool/go get github.com/tailscale/web-client-prebuilt
./tool/go mod tidy
- name: Get access token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
id: generate-token
with:
# Get token for app: https://github.com/apps/tailscale-code-updater
app-id: ${{ secrets.CODE_UPDATER_APP_ID }}
private-key: ${{ secrets.CODE_UPDATER_APP_PRIVATE_KEY }}
- name: Send pull request
id: pull-request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 #v8.1.0
with:
token: ${{ steps.generate-token.outputs.token }}
author: OSS Updater <noreply+oss-updater@tailscale.com>
committer: OSS Updater <noreply+oss-updater@tailscale.com>
branch: actions/update-webclient-prebuilt
commit-message: "go.mod: update web-client-prebuilt module"
title: "go.mod: update web-client-prebuilt module"
body: Triggered by ${{ github.repository }}@${{ github.sha }}
signoff: true
delete-branch: true
reviewers: ${{ github.triggering_actor }}
- name: Summary
if: ${{ steps.pull-request.outputs.pull-request-number }}
run: echo "${{ steps.pull-request.outputs.pull-request-operation}} ${{ steps.pull-request.outputs.pull-request-url }}" >> $GITHUB_STEP_SUMMARY
+45
View File
@@ -0,0 +1,45 @@
name: tailscale.com/cmd/vet
env:
HOME: ${{ github.workspace }}
# GOMODCACHE is the same definition on all OSes. Within the workspace, we use
# toplevel directories "src" (for the checked out source code), and "gomodcache"
# and other caches as siblings to follow.
GOMODCACHE: ${{ github.workspace }}/gomodcache
CMD_GO_USE_GIT_HASH: "true"
on:
push:
branches:
- main
- "release-branch/*"
paths:
- "**.go"
pull_request:
paths:
- "**.go"
jobs:
vet:
runs-on: [ self-hosted, linux ]
timeout-minutes: 5
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: src
- name: Build 'go vet' tool
working-directory: src
run: ./tool/go build -o /tmp/vettool tailscale.com/cmd/vet
- name: Run 'go vet'
working-directory: src
# Use listpkgs --ignore-3p to skip tempfork/ packages, which
# intentionally match upstream and may not follow our style rules.
# Must use ./... instead of tailscale.com/... because the latter will
# include the v2 go client (tailscale.com/client/tailscale/v2) if it's
# a dependency in our go.mod file. Possibly a go vet bug, but avoid
# cross-repo vetting for now so we can safely add the dependency.
run: ./tool/go vet -vettool=/tmp/vettool $(./tool/go run ./tool/listpkgs --ignore-3p ./...)
+38
View File
@@ -0,0 +1,38 @@
name: webclient
on:
workflow_dispatch:
# For now, only run on requests, not the main branches.
pull_request:
paths:
- "client/web/**"
- ".github/workflows/webclient.yml"
- "!**.md"
# TODO(soniaappasamy): enable for main branch after an initial waiting period.
#push:
# branches:
# - main
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
webclient:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install deps
run: ./tool/yarn --cwd client/web
- name: Run lint
run: ./tool/yarn --cwd client/web run --silent lint
- name: Run test
run: ./tool/yarn --cwd client/web run --silent test
- name: Run formatter check
run: |
./tool/yarn --cwd client/web run --silent format-check || ( \
echo "Run this command on your local device to fix the error:" && \
echo "" && \
echo " ./tool/yarn --cwd client/web format" && \
echo "" && exit 1)