mirror of
https://github.com/lukaszraczylo/kportal.git
synced 2026-06-05 23:03:40 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 690c587c0a | |||
| 0d03f228f9 | |||
| 2a44c6ff9c | |||
| 8672d932bb | |||
| 87317adb91 | |||
| ced7e80a06 | |||
| 13723733df | |||
| 9538623bcb | |||
| 8bb377909c | |||
| 263a0370d3 | |||
| 62eca4a9a1 | |||
| ea20a037b9 | |||
| 46db732f87 |
@@ -5,69 +5,13 @@ on:
|
||||
schedule:
|
||||
- cron: "0 3 * * *"
|
||||
|
||||
env:
|
||||
GO_VERSION: ">=1.21"
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
# This job is responsible for preparation of the build
|
||||
# environment variables.
|
||||
prepare:
|
||||
name: Preparing build context
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
id: cache
|
||||
with:
|
||||
go-version: ${{env.GO_VERSION}}
|
||||
cache-dependency-path: "**/*.sum"
|
||||
|
||||
- name: Go get dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
go get ./...
|
||||
|
||||
# This job is responsible for running tests and linting the codebase
|
||||
test:
|
||||
name: "Unit testing"
|
||||
runs-on: ubuntu-latest
|
||||
container: golang:1
|
||||
needs: [prepare]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Ensure full history is checked out
|
||||
token: ${{ secrets.GHCR_TOKEN }}
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{env.GO_VERSION}}
|
||||
cache-dependency-path: "**/*.sum"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install ca-certificates make -y
|
||||
update-ca-certificates
|
||||
go mod tidy
|
||||
go get -u -v ./...
|
||||
go mod tidy -v
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
CI_RUN=${CI} make test
|
||||
git config --global --add safe.directory /__w/kportal/kportal
|
||||
|
||||
- name: Commit changes
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "Update go.mod and go.sum"
|
||||
commit_options: "--no-verify --signoff"
|
||||
file_pattern: "go.mod go.sum"
|
||||
autoupdate:
|
||||
uses: lukaszraczylo/shared-actions/.github/workflows/go-autoupdate.yaml@main
|
||||
with:
|
||||
go-version: ">=1.21"
|
||||
release-workflow: "release.yml"
|
||||
|
||||
@@ -5,90 +5,18 @@ on:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- '**.go'
|
||||
- 'go.mod'
|
||||
- 'go.sum'
|
||||
- "**.go"
|
||||
- "go.mod"
|
||||
- "go.sum"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
|
||||
- name: Run tests with race detector
|
||||
run: go test -race -v ./...
|
||||
|
||||
version:
|
||||
name: Calculate Version
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.version_formatted.outputs.version }}
|
||||
version_tag: ${{ steps.version_formatted.outputs.version_tag }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Calculate semantic version
|
||||
id: semver
|
||||
uses: lukaszraczylo/semver-generator@v1
|
||||
with:
|
||||
config_file: semver.yaml
|
||||
repository_local: true
|
||||
|
||||
- name: Format version
|
||||
id: version_formatted
|
||||
run: |
|
||||
VERSION="${{ steps.semver.outputs.semantic_version }}"
|
||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||
echo "version_tag=v${VERSION}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Display version
|
||||
run: |
|
||||
echo "Calculated version: ${{ steps.version_formatted.outputs.version }}"
|
||||
echo "Version tag: ${{ steps.version_formatted.outputs.version_tag }}"
|
||||
|
||||
release:
|
||||
name: Release with GoReleaser
|
||||
needs: version
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
|
||||
- name: Create and push tag
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git tag -a ${{ needs.version.outputs.version_tag }} -m "Release ${{ needs.version.outputs.version_tag }}"
|
||||
git push origin ${{ needs.version.outputs.version_tag }}
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: '~> v2'
|
||||
args: release --clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
||||
uses: lukaszraczylo/shared-actions/.github/workflows/go-release.yaml@main
|
||||
with:
|
||||
go-version: "1.23"
|
||||
secrets:
|
||||
homebrew-tap-token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
||||
|
||||
+9
-9
@@ -23,11 +23,11 @@ builds:
|
||||
|
||||
archives:
|
||||
- id: kportal
|
||||
format: tar.gz
|
||||
formats: [tar.gz]
|
||||
name_template: "kportal-{{ .Version }}-{{ .Os }}-{{ .Arch }}"
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
format: zip
|
||||
formats: [zip]
|
||||
files:
|
||||
- LICENSE
|
||||
- README.md
|
||||
@@ -53,17 +53,17 @@ release:
|
||||
draft: false
|
||||
prerelease: auto
|
||||
|
||||
brews:
|
||||
homebrew_casks:
|
||||
- repository:
|
||||
owner: lukaszraczylo
|
||||
name: homebrew-taps
|
||||
token: "{{ .Env.HOMEBREW_TAP_TOKEN }}"
|
||||
directory: Formula
|
||||
directory: Casks
|
||||
homepage: https://lukaszraczylo.github.io/kportal
|
||||
description: "Modern Kubernetes port-forward manager with interactive TUI"
|
||||
license: MIT
|
||||
test: |
|
||||
system "#{bin}/kportal", "--version"
|
||||
dependencies:
|
||||
- name: kubernetes-cli
|
||||
type: optional
|
||||
hooks:
|
||||
post:
|
||||
install: |
|
||||
system_command "/usr/bin/xattr",
|
||||
args: ["-dr", "com.apple.quarantine", "#{staged_path}/kportal"]
|
||||
|
||||
@@ -54,12 +54,17 @@ kportal manages multiple Kubernetes port-forwards with an interactive terminal i
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
### Homebrew (macOS/Linux)
|
||||
### Homebrew (macOS)
|
||||
|
||||
```bash
|
||||
brew install lukaszraczylo/taps/kportal
|
||||
brew install --cask lukaszraczylo/taps/kportal
|
||||
```
|
||||
|
||||
> **Note**: If you previously installed via `brew install lukaszraczylo/taps/kportal` (formula), uninstall first:
|
||||
> ```bash
|
||||
> brew uninstall kportal
|
||||
> ```
|
||||
|
||||
### Quick Install
|
||||
|
||||
```bash
|
||||
|
||||
+3
-3
@@ -556,11 +556,11 @@
|
||||
<i class="fas fa-beer text-orange-500 dark:text-orange-400 text-2xl mr-3"></i>
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-gray-100">Homebrew</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400 text-sm">macOS & Linux</p>
|
||||
<p class="text-gray-600 dark:text-gray-400 text-sm">macOS</p>
|
||||
</div>
|
||||
</div>
|
||||
<div onclick="copyToClipboard('brew install lukaszraczylo/taps/kportal', this)" class="relative bg-gradient-to-br from-gray-900 to-gray-800 dark:from-gray-950 dark:to-black text-gray-100 p-4 rounded-lg text-sm cursor-pointer group overflow-x-auto border border-gray-700 hover:border-orange-500 transition-all duration-300">
|
||||
<code class="block whitespace-nowrap font-mono">brew install lukaszraczylo/taps/kportal</code>
|
||||
<div onclick="copyToClipboard('brew install --cask lukaszraczylo/taps/kportal', this)" class="relative bg-gradient-to-br from-gray-900 to-gray-800 dark:from-gray-950 dark:to-black text-gray-100 p-4 rounded-lg text-sm cursor-pointer group overflow-x-auto border border-gray-700 hover:border-orange-500 transition-all duration-300">
|
||||
<code class="block whitespace-nowrap font-mono">brew install --cask lukaszraczylo/taps/kportal</code>
|
||||
<div class="absolute top-3 right-3"><i class="fas fa-copy text-gray-500 group-hover:text-orange-400 transition-colors duration-300"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -20,10 +20,10 @@ require (
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/charmbracelet/colorprofile v0.3.3 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.11.1 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.11.2 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.14 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.2 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.6.0 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.6.1 // indirect
|
||||
github.com/clipperhouse/stringish v0.1.1 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
|
||||
@@ -12,16 +12,16 @@ github.com/charmbracelet/colorprofile v0.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGx
|
||||
github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4=
|
||||
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
||||
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
||||
github.com/charmbracelet/x/ansi v0.11.1 h1:iXAC8SyMQDJgtcz9Jnw+HU8WMEctHzoTAETIeA3JXMk=
|
||||
github.com/charmbracelet/x/ansi v0.11.1/go.mod h1:M49wjzpIujwPceJ+t5w3qh2i87+HRtHohgb5iTyepL0=
|
||||
github.com/charmbracelet/x/ansi v0.11.2 h1:XAG3FSjiVtFvgEgGrNBkCNNYrsucAt8c6bfxHyROLLs=
|
||||
github.com/charmbracelet/x/ansi v0.11.2/go.mod h1:9tY2bzX5SiJCU0iWyskjBeI2BRQfvPqI+J760Mjf+Rg=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA=
|
||||
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
|
||||
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
|
||||
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
|
||||
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
|
||||
github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s=
|
||||
github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
||||
github.com/clipperhouse/displaywidth v0.6.1 h1:/zMlAezfDzT2xy6acHBzwIfyu2ic0hgkT83UX5EY2gY=
|
||||
github.com/clipperhouse/displaywidth v0.6.1/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
||||
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
||||
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
|
||||
|
||||
@@ -221,10 +221,3 @@ func (r *Runner) makeRequest(ctx context.Context, cfg Config) (statusCode int, b
|
||||
|
||||
return resp.StatusCode, int64(len(respBody)), bytesWritten, nil
|
||||
}
|
||||
|
||||
// Progress represents the current progress of a benchmark run
|
||||
type Progress struct {
|
||||
Completed int
|
||||
Total int
|
||||
Elapsed time.Duration
|
||||
}
|
||||
|
||||
@@ -89,6 +89,11 @@ func (p *Publisher) Register(forwardID, alias string, localPort int) error {
|
||||
p.servers[forwardID] = server
|
||||
p.aliases[forwardID] = alias
|
||||
|
||||
// Allow zeroconf's internal goroutines (recv4, recv6) to fully initialize.
|
||||
// This prevents a race condition where shutdown() could set connections to nil
|
||||
// while recv goroutines are still starting up.
|
||||
time.Sleep(startupSettleTime)
|
||||
|
||||
logger.Info("mDNS hostname registered", map[string]interface{}{
|
||||
"forward_id": forwardID,
|
||||
"hostname": GetHostname(alias),
|
||||
@@ -151,6 +156,13 @@ func (p *Publisher) Stop() {
|
||||
logger.Info("mDNS publisher stopped", nil)
|
||||
}
|
||||
|
||||
// startupSettleTime is a small delay after zeroconf registration to allow internal
|
||||
// goroutines (recv4, recv6) to fully initialize before any shutdown can occur.
|
||||
// This works around a race condition in grandcat/zeroconf where shutdown() sets
|
||||
// connections to nil while recv goroutines may still be initializing.
|
||||
// See: https://github.com/grandcat/zeroconf/issues/95
|
||||
const startupSettleTime = 50 * time.Millisecond
|
||||
|
||||
// shutdownSettleTime is a small delay after zeroconf shutdown to allow internal
|
||||
// goroutines to exit cleanly. This works around a race condition in the
|
||||
// grandcat/zeroconf library where recv4() can access ipv4conn after shutdown()
|
||||
|
||||
Reference in New Issue
Block a user