Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.git
.github
.claude
.agents
.codex
docs
scripts
uploads
upgopher
coverage.out
*.log
.DS_Store
77 changes: 77 additions & 0 deletions .github/release-notes/v1.20.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Upgopher v1.20.0 — easier to discover, install, and choose

Upgopher v1.20.0 is an adoption release. The server's routes, flags,
authentication behavior, and file formats remain compatible with v1.19.1.

## What is new

- A shorter README centered on getting from a directory to a browser in one
command.
- A product website with installation, configuration, security, and
troubleshooting documentation.
- Project-maintained multi-architecture images on Docker Hub and GHCR.
- Project-maintained Homebrew and Scoop distribution.
- Refreshed product captures and an honest comparison with Python's
`http.server`, Dufs, File Browser, and Copyparty.
- Release automation that creates a draft for verification before publication.

## Install

```bash
# macOS
brew install --cask wanetty/tap/upgopher

# Windows
scoop bucket add wanetty https://github.com/wanetty/scoop-bucket
scoop install upgopher

# Docker
docker run --rm -p 9090:9090 -v "$PWD:/data" wanetty/upgopher:1.20.0

# With Go
go install github.com/wanetty/upgopher@latest
```

Release archives for Linux, macOS, and Windows are attached below. Verify a
download against `checksums.txt` before running it.

## Compatibility

No HTTP routes, flags, authentication behavior, or file formats changed.
Existing installations can keep their current command line and data directory.

The Linux release archive names and embedded binary path remain compatible with
the Upgopher installer maintained by Proxmox Community Scripts. Existing LXC
instances continue using `/opt/upgopher/uploads` and their current systemd
service during updates.

## Container notes

The image now runs as the non-root UID/GID `65532`, serves `/data`, and keeps a
writable `/tmp` for temporary ZIP files. Bind-mounted directories must grant
that identity the permissions required by your chosen mode.

Use the exact `1.20.0` tag for predictable deployments. `1.20`, `1`, and
`latest` are convenience tags that can move.

## Intentional limits

Upgopher remains a compact browser-sharing server. It does not add WebDAV,
resumable uploads, multi-user roles, storage backends, or a persistent
administration database in this release.

## Validation

- `make test`
- `make test-race`
- `make lint`
- `make build`
- GoReleaser v2 snapshot, archives, and checksums
- Linux `amd64` and `arm64` Community Scripts release contract
- Non-root container smoke tests for uploads, read-only mode, Basic Auth, TLS,
and ZIP downloads
- Desktop and mobile documentation checks

See the [getting-started guide](https://wanetty.github.io/upgopher/getting-started.html)
and [security guide](https://wanetty.github.io/upgopher/security.html) before
exposing an instance beyond a trusted network.
82 changes: 82 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: CI

on:
push:
branches:
- main
- dev
pull_request:

permissions:
contents: read

jobs:
test:
name: Go / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "1.24.x"
cache: false

- name: Test
run: go test ./...

- name: Vet
run: go vet ./...

- name: Build
run: go build -trimpath ./...

race:
name: Race detector
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "1.24.x"
cache: false

- name: Test with race detector
run: go test -race ./...

release-contract:
name: Release / Community Scripts contract
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "1.24.x"
cache: false

- name: Build release snapshot
uses: goreleaser/goreleaser-action@v7
with:
distribution: goreleaser
version: "~> v2"
args: release --snapshot --clean --skip=publish

- name: Verify Community Scripts compatibility
run: ./scripts/check-community-scripts-contract.sh
67 changes: 67 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Container

on:
push:
tags:
- "v*"

permissions:
contents: read
packages: write

jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Generate image metadata
id: metadata
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/wanetty/upgopher
wanetty/upgopher
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable=${{ !contains(github.ref_name, '-') }}
labels: |
org.opencontainers.image.title=Upgopher
org.opencontainers.image.description=A self-contained browser file and clipboard sharing server

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
build-args: |
VERSION=${{ steps.metadata.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: mode=max
sbom: true
32 changes: 0 additions & 32 deletions .github/workflows/go.yml

This file was deleted.

40 changes: 40 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Pages

on:
push:
branches:
- main
paths:
- "docs/**"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Configure Pages
uses: actions/configure-pages@v5

- name: Upload site
uses: actions/upload-pages-artifact@v3
with:
path: docs

- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
62 changes: 62 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Release

on:
push:
tags:
- "v*"

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "1.24.x"
cache: false

- name: Test
run: go test ./...

- name: Vet
run: go vet ./...

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v7
with:
distribution: goreleaser
version: "~> v2"
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DISTRIBUTION_GITHUB_TOKEN: ${{ secrets.DISTRIBUTION_GITHUB_TOKEN }}

- name: Checkout Scoop bucket
uses: actions/checkout@v5
with:
repository: wanetty/scoop-bucket
token: ${{ secrets.DISTRIBUTION_GITHUB_TOKEN }}
path: scoop-bucket

- name: Add Scoop update metadata
run: go run ./scripts/enrich-scoop-manifest ./scoop-bucket/upgopher.json

- name: Publish Scoop update metadata
working-directory: scoop-bucket
run: |
if git diff --quiet -- upgopher.json; then
exit 0
fi
git config user.name upgopher-release
git config user.email noreply@upgopher.dev
git add upgopher.json
git commit -m "chore: add Upgopher update metadata"
git push
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*.so
*.dylib
upgopher
dist/
# Test binary, built with `go test -c`
*.test

Expand All @@ -16,5 +17,4 @@ upgopher
# Dependency directories (remove the comment below to include it)
# vendor/
uploads/
.github/*
.agents/*
.agents/
Loading