Skip to content

feat: add env group rendering and sync nodes preview #1268 #2960

feat: add env group rendering and sync nodes preview #1268

feat: add env group rendering and sync nodes preview #1268 #2960

Workflow file for this run

name: Build
on:
push:
branches-ignore:
- 'weblate'
paths:
- "app/**/*.js"
- "app/**/*.ts"
- "app/**/*.vue"
- "app/src/language/**/*.po"
- "app/i18n.json"
- "app/package.json"
- "app/.env*"
- "**/*.go"
- "go.mod"
- "go.sum"
- ".github/workflows/build*.yml"
- "resources/docker/docker/*"
- "resources/development/*"
- "resources/demo/*"
- "Dockerfile"
- "demo.Dockerfile"
pull_request:
types: [ opened, synchronize, reopened ]
paths:
- "**/*.js"
- "**/*.vue"
- "app/package.json"
- "app/.env*"
- "**/*.go"
- "go.mod"
- "go.sum"
- ".github/workflows/*.yml"
- "resources/docker/docker/*"
- "resources/development/*"
- "resources/demo/*"
release:
types:
- published
jobs:
build_app:
runs-on: macos-14
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up nodejs
uses: actions/setup-node@v4
with:
node-version: current
- name: Install dependencies
run: |
corepack enable
corepack prepare pnpm@latest --activate
pnpm install
working-directory: app
- name: Check frontend code style
run: |
pnpm run lint
working-directory: app
- name: Check frontend types
run: |
pnpm run typecheck
working-directory: app
- name: Build
run: |
npx update-browserslist-db@latest
pnpm build
working-directory: app
- name: Archive app artifacts
uses: actions/upload-artifact@v4
with:
name: app-dist
path: app/dist
- name: Prepare publish
if: github.event_name == 'release'
run: |
cp README*.md app/dist
find app/dist -printf '%P\n' | tar -C app/dist --no-recursion -zcvf app-dist.tar.gz -T -
- name: Publish
uses: softprops/action-gh-release@v2
if: github.event_name == 'release'
with:
files: app-dist.tar.gz
build:
runs-on: ubuntu-latest
needs: build_app
strategy:
matrix:
goos: [ linux, darwin, windows ]
goarch: [ amd64, 386, arm64 ]
exclude:
# Exclude i386 on darwin.
- goarch: 386
goos: darwin
include:
# BEGIN Linux ARM 5 6 7
- goos: linux
goarch: arm
goarm: 7
- goos: linux
goarch: arm
goarm: 6
- goos: linux
goarch: arm
goarm: 5
# END Linux ARM 5 6 7
- goos: linux
goarch: riscv64
- goos: linux
goarch: loong64
# BEGIN MIPS
- goos: linux
goarch: mips64
- goos: linux
goarch: mips64le
- goos: linux
goarch: mipsle
- goos: linux
goarch: mips
# END MIPS
env:
CGO_ENABLED: 1
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
GOARM: ${{ matrix.goarm }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ^1.24.5
cache: false
- name: Setup environment
id: info
run: |
export _NAME=$(jq ".$GOOS[\"$GOARCH$GOARM\"].name" -r < .github/build/build_info.json)
export _ARCH=$(jq ".$GOOS[\"$GOARCH$GOARM\"].arch" -r < .github/build/build_info.json)
export _ABI=$(jq ".$GOOS[\"$GOARCH$GOARM\"].abi // \"\"" -r < .github/build/build_info.json)
export _ARTIFACT=nginx-ui-$GOOS-$GOARCH$(if [[ "$GOARM" ]]; then echo "v$GOARM"; fi)
export _BINARY=nginx-ui$(if [[ "$GOOS" == "windows" ]]; then echo ".exe"; fi)
echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, ABI: $_ABI, RELEASE_NAME: $_NAME, ARTIFACT_NAME: $_ARTIFACT, BINARY_NAME: $_BINARY"
echo "CACHE_NAME=$_NAME" >> $GITHUB_ENV
echo "ARCH_NAME=$_ARCH" >> $GITHUB_ENV
echo "ABI=$_ABI" >> $GITHUB_ENV
echo "DIST=nginx-ui-$_NAME" >> $GITHUB_ENV
echo "ARTIFACT=$_ARTIFACT" >> $GITHUB_ENV
echo "BINARY_NAME=$_BINARY" >> $GITHUB_ENV
- name: Setup Go modules cache
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
key: go-${{ runner.os }}-${{ runner.arch }}-mod-${{ hashFiles('go.mod') }}
restore-keys: |
go-${{ runner.os }}-${{ runner.arch }}-mod-
- name: Setup Go build cache
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
key: go-${{ runner.os }}-${{ runner.arch }}-${{ env.CACHE_NAME }}-${{ hashFiles('go.mod') }}
restore-keys: |
go-${{ runner.os }}-${{ runner.arch }}-${{ env.CACHE_NAME }}-
- name: Download app artifacts
uses: actions/download-artifact@v4
with:
name: app-dist
path: app/dist
- name: Generate files
env:
GOOS: linux
GOARCH: amd64
run: go generate cmd/version/generate.go
- name: Install musl cross compiler
if: env.GOOS == 'linux'
uses: nginxui/musl-cross-compilers@v1
id: musl
with:
target: ${{ env.ARCH_NAME }}-linux-musl${{ env.ABI }}
variant: ${{ env.GOARCH == 'loong64' && 'userdocs/qbt-musl-cross-make' || 'richfelker/musl-cross-make' }}
- name: Post install musl cross compiler
if: env.GOOS == 'linux'
run: |
echo "PATH=${{ steps.musl.outputs.path }}:$PATH" >> $GITHUB_ENV
echo "CC=${{ env.ARCH_NAME }}-linux-musl${{ env.ABI }}-gcc" >> $GITHUB_ENV
echo "CXX=${{ env.ARCH_NAME }}-linux-musl${{ env.ABI }}-g++" >> $GITHUB_ENV
echo "LD_FLAGS=-w --extldflags '-static'" >> $GITHUB_ENV
- name: Install darwin cross compiler
if: env.GOOS == 'darwin'
run: |
curl -L https://github.com/Hintay/crossosx/releases/latest/download/crossosx.tar.zst -o crossosx.tar.zst
tar xvaf crossosx.tar.zst
echo "LD_LIBRARY_PATH=$(pwd)/crossosx/lib/" >> $GITHUB_ENV
echo "PATH=$(pwd)/crossosx/bin/:$PATH" >> $GITHUB_ENV
echo "CC=${{ env.ARCH_NAME }}-clang" >> $GITHUB_ENV
echo "CXX=${{ env.ARCH_NAME }}-clang++" >> $GITHUB_ENV
echo "LD_FLAGS=-w" >> $GITHUB_ENV
- name: Setup for Windows
if: env.GOOS == 'windows'
run: |
echo "LD_FLAGS=-w" >> $GITHUB_ENV
echo "CGO_ENABLED=1" >> $GITHUB_ENV
# Install cross compilers based on architecture
sudo apt-get update
sudo apt-get install -y zip
if [[ "$GOARCH" == "amd64" ]]; then
echo "Installing x86_64 Windows cross compiler"
sudo apt-get install -y gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64
echo "CC=x86_64-w64-mingw32-gcc" >> $GITHUB_ENV
echo "CXX=x86_64-w64-mingw32-g++" >> $GITHUB_ENV
elif [[ "$GOARCH" == "386" ]]; then
echo "Installing i686 Windows cross compiler"
sudo apt-get install -y gcc-mingw-w64-i686 g++-mingw-w64-i686
echo "CC=i686-w64-mingw32-gcc" >> $GITHUB_ENV
echo "CXX=i686-w64-mingw32-g++" >> $GITHUB_ENV
elif [[ "$GOARCH" == "arm64" ]]; then
echo "Installing ARM64 Windows cross compiler"
# Ubuntu's apt repositories don't have mingw for ARM64
# Use llvm-mingw project instead
mkdir -p $HOME/llvm-mingw
wget -q https://github.com/mstorsjo/llvm-mingw/releases/download/20231128/llvm-mingw-20231128-ucrt-ubuntu-20.04-x86_64.tar.xz
tar xf llvm-mingw-20231128-ucrt-ubuntu-20.04-x86_64.tar.xz -C $HOME/llvm-mingw --strip-components=1
echo "PATH=$HOME/llvm-mingw/bin:$PATH" >> $GITHUB_ENV
echo "CC=aarch64-w64-mingw32-clang" >> $GITHUB_ENV
echo "CXX=aarch64-w64-mingw32-clang++" >> $GITHUB_ENV
else
echo "Unsupported Windows architecture: $GOARCH"
exit 1
fi
- name: Build
run: |
mkdir -p dist
go build -trimpath -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o dist/$BINARY_NAME -v main.go
- name: Archive backend artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT }}
path: dist/${{ env.BINARY_NAME }}
- name: Prepare publish
run: |
cp README*.md ./dist
find dist -printf '%P\n' | tar -C dist --no-recursion -zcvf ${{ env.DIST }}.tar.gz -T -
openssl dgst -sha512 ${{ env.DIST }}.tar.gz | sed 's/([^)]*)//g' | awk '{print $NF}' >> ${{ env.DIST }}.tar.gz.digest
# Create zip for Windows builds (for winget compatibility)
if [[ "$GOOS" == "windows" ]]; then
cd dist
zip -r ../${{ env.DIST }}.zip .
cd ..
openssl dgst -sha512 ${{ env.DIST }}.zip | sed 's/([^)]*)//g' | awk '{print $NF}' >> ${{ env.DIST }}.zip.digest
fi
- name: Publish
uses: softprops/action-gh-release@v2
if: github.event_name == 'release'
with:
files: |
${{ env.DIST }}.tar.gz
${{ env.DIST }}.tar.gz.digest
${{ env.GOOS == 'windows' && format('{0}.zip', env.DIST) || '' }}
${{ env.GOOS == 'windows' && format('{0}.zip.digest', env.DIST) || '' }}
- name: Upload to R2 using S3 API
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/dev'
env:
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-1
run: |
echo "Uploading ${{ env.DIST }}.tar.gz to R2..."
aws s3 cp ./${{ env.DIST }}.tar.gz s3://nginx-ui-dev-build/${{ env.DIST }}.tar.gz --endpoint-url=${{ secrets.R2_S3_API_ENDPOINT }}
echo "Uploading ${{ env.DIST }}.tar.gz.digest to R2..."
aws s3 cp ./${{ env.DIST }}.tar.gz.digest s3://nginx-ui-dev-build/${{ env.DIST }}.tar.gz.digest --endpoint-url=${{ secrets.R2_S3_API_ENDPOINT }}
echo "Upload completed successfully"
docker-build:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
needs: build
env:
PLATFORMS: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/arm/v5
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
uozi/nginx-ui
tags: |
type=schedule
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{raw}}
type=sha
type=raw,value=latest,enable=${{ github.event_name == 'release' && !github.event.release.prerelease }}
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: ./dist
- name: Prepare Artifacts
run: chmod +x ./dist/nginx-ui-*/nginx-ui*
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Prepare Dockerfile
run: |
cp ./Dockerfile ./dist
cp -rp ./resources ./dist
- name: Build and push
uses: docker/build-push-action@v6
with:
context: ./dist
file: ./dist/Dockerfile
platforms: ${{ env.PLATFORMS }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Prepare Demo Dockerfile
run: |
cp ./demo.Dockerfile ./dist
cp -rp ./resources ./dist
- name: Build and push demo
uses: docker/build-push-action@v6
if: github.ref == 'refs/heads/dev'
with:
context: ./dist
file: ./dist/demo.Dockerfile
platforms: ${{ env.PLATFORMS }}
push: 'true'
tags: |
uozi/nginx-ui-demo:latest
update-homebrew:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'release'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get release info
id: release
run: |
echo "tag_name=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Download release assets and calculate SHA256 checksums
id: checksums
run: |
VERSION="${{ steps.release.outputs.version }}"
TAG_NAME="${{ steps.release.outputs.tag_name }}"
# Download binary files from releases and calculate SHA256
mkdir -p downloads
# macOS Intel
wget -O downloads/nginx-ui-macos-64.tar.gz "https://github.com/${{ github.repository }}/releases/download/$TAG_NAME/nginx-ui-macos-64.tar.gz"
MACOS_INTEL_SHA256=$(sha256sum downloads/nginx-ui-macos-64.tar.gz | cut -d' ' -f1)
# macOS ARM
wget -O downloads/nginx-ui-macos-arm64-v8a.tar.gz "https://github.com/${{ github.repository }}/releases/download/$TAG_NAME/nginx-ui-macos-arm64-v8a.tar.gz"
MACOS_ARM_SHA256=$(sha256sum downloads/nginx-ui-macos-arm64-v8a.tar.gz | cut -d' ' -f1)
# Linux Intel
wget -O downloads/nginx-ui-linux-64.tar.gz "https://github.com/${{ github.repository }}/releases/download/$TAG_NAME/nginx-ui-linux-64.tar.gz"
LINUX_INTEL_SHA256=$(sha256sum downloads/nginx-ui-linux-64.tar.gz | cut -d' ' -f1)
# Linux ARM
wget -O downloads/nginx-ui-linux-arm64-v8a.tar.gz "https://github.com/${{ github.repository }}/releases/download/$TAG_NAME/nginx-ui-linux-arm64-v8a.tar.gz"
LINUX_ARM_SHA256=$(sha256sum downloads/nginx-ui-linux-arm64-v8a.tar.gz | cut -d' ' -f1)
echo "macos_intel_sha256=$MACOS_INTEL_SHA256" >> $GITHUB_OUTPUT
echo "macos_arm_sha256=$MACOS_ARM_SHA256" >> $GITHUB_OUTPUT
echo "linux_intel_sha256=$LINUX_INTEL_SHA256" >> $GITHUB_OUTPUT
echo "linux_arm_sha256=$LINUX_ARM_SHA256" >> $GITHUB_OUTPUT
- name: Generate Homebrew Formula
id: formula
run: |
VERSION="${{ steps.release.outputs.version }}"
cat > nginx-ui.rb << 'EOF'
class NginxUi < Formula
desc "Yet another Nginx Web UI"
homepage "https://github.com/0xJacky/nginx-ui"
version "${{ steps.release.outputs.version }}"
license "AGPL-3.0"
on_macos do
on_intel do
url "https://github.com/0xJacky/nginx-ui/releases/download/v#{version}/nginx-ui-macos-64.tar.gz"
sha256 "${{ steps.checksums.outputs.macos_intel_sha256 }}"
end
on_arm do
url "https://github.com/0xJacky/nginx-ui/releases/download/v#{version}/nginx-ui-macos-arm64-v8a.tar.gz"
sha256 "${{ steps.checksums.outputs.macos_arm_sha256 }}"
end
end
on_linux do
on_intel do
url "https://github.com/0xJacky/nginx-ui/releases/download/v#{version}/nginx-ui-linux-64.tar.gz"
sha256 "${{ steps.checksums.outputs.linux_intel_sha256 }}"
end
on_arm do
url "https://github.com/0xJacky/nginx-ui/releases/download/v#{version}/nginx-ui-linux-arm64-v8a.tar.gz"
sha256 "${{ steps.checksums.outputs.linux_arm_sha256 }}"
end
end
def install
bin.install "nginx-ui"
# Create configuration directory
(etc/"nginx-ui").mkpath
# Create default configuration file if it doesn't exist
config_file = etc/"nginx-ui/app.ini"
unless config_file.exist?
config_file.write <<~EOS
[app]
PageSize = 10
[server]
Host = 0.0.0.0
Port = 9000
RunMode = release
[cert]
HTTPChallengePort = 9180
[terminal]
StartCmd = login
EOS
end
# Create data directory
(var/"nginx-ui").mkpath
end
def post_install
# Ensure correct permissions
(var/"nginx-ui").chmod 0755
end
service do
run [opt_bin/"nginx-ui", "serve", "--config", etc/"nginx-ui/app.ini"]
keep_alive true
working_dir var/"nginx-ui"
log_path var/"log/nginx-ui.log"
error_log_path var/"log/nginx-ui.err.log"
end
test do
assert_match version.to_s, shell_output("#{bin}/nginx-ui --version")
end
end
EOF
echo "Generated Homebrew Formula:"
cat nginx-ui.rb
- name: Checkout homebrew-tools repository
uses: actions/checkout@v4
with:
repository: 0xJacky/homebrew-tools
path: homebrew-tools
token: ${{ secrets.HOMEBREW_GITHUB_TOKEN }}
- name: Update Formula file
run: |
# Copy the generated formula to the correct location
mkdir -p homebrew-tools/Formula/
cp nginx-ui.rb homebrew-tools/Formula/nginx-ui.rb
- name: Verify Formula
run: |
cd homebrew-tools
# Basic syntax check
ruby -c Formula/nginx-ui.rb
echo "Formula syntax is valid"
- name: Create Pull Request to homebrew-tools
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.HOMEBREW_GITHUB_TOKEN }}
path: homebrew-tools
branch: update-nginx-ui-${{ steps.release.outputs.version }}
delete-branch: true
title: 'nginx-ui ${{ steps.release.outputs.version }}'
body: |
Update nginx-ui to version ${{ steps.release.outputs.version }}
**Release Notes:**
- Version: ${{ steps.release.outputs.version }}
- Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ steps.release.outputs.tag_name }}
**Checksums (SHA256):**
- macOS Intel: ${{ steps.checksums.outputs.macos_intel_sha256 }}
- macOS ARM: ${{ steps.checksums.outputs.macos_arm_sha256 }}
- Linux Intel: ${{ steps.checksums.outputs.linux_intel_sha256 }}
- Linux ARM: ${{ steps.checksums.outputs.linux_arm_sha256 }}
---
This PR was automatically generated by GitHub Actions.
commit-message: 'nginx-ui ${{ steps.release.outputs.version }}'
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
add-paths: |
Formula/nginx-ui.rb
publish-winget:
runs-on: windows-latest
needs: build
if: github.event_name == 'release'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Publish to WinGet
uses: vedantmgoyal9/winget-releaser@v2
with:
identifier: 0xJacky.nginx-ui
max-versions-to-keep: 5
token: ${{ secrets.HOMEBREW_GITHUB_TOKEN }}
installers-regex: 'nginx-ui-windows.*\.zip$'