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
31 changes: 28 additions & 3 deletions .github/workflows/build-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,27 @@ on:
branches: [ main, master ]
workflow_dispatch:

# Pull requests and ordinary builds receive only repository read access. The
# release job elevates this explicitly when it creates a tagged GitHub release.
permissions:
contents: read

jobs:
verify-release-version:
name: Verify release tag matches client version
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
persist-credentials: false

- name: Verify tagged release version
if: github.ref_type == 'tag'
run: node scripts/check-release-version.cjs "$GITHUB_REF_NAME"

build:
needs: verify-release-version
runs-on: ${{ matrix.os }}
continue-on-error: false

Expand All @@ -21,6 +40,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@v6
Expand Down Expand Up @@ -387,7 +408,9 @@ jobs:
- name: Build Electron app
run: npm run dist
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Only tagged release builds receive a token; PR and branch builds never
# expose a credential to package scripts or electron-builder hooks.
GH_TOKEN: ${{ github.ref_type == 'tag' && secrets.GITHUB_TOKEN || '' }}
CI: true
DEBUG: electron-builder
# Linux 特定环境变量
Expand Down Expand Up @@ -452,9 +475,11 @@ jobs:
if-no-files-found: ignore

release:
needs: build
needs: [verify-release-version, build]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v') && always()
# Keep partial platform releases possible, but never publish when the tag
# does not match the root package.json client version.
if: always() && startsWith(github.ref, 'refs/tags/v') && needs.verify-release-version.result == 'success'
permissions:
contents: write

Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/docker-publish-frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ jobs:
with:
persist-credentials: false

- name: Verify release tag matches client version
if: github.ref_type == 'tag'
run: node scripts/check-release-version.cjs "$GITHUB_REF_NAME"

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

Expand All @@ -53,6 +57,7 @@ jobs:
# branch push → "latest"
type=raw,value=latest,enable={{is_default_branch}}
# tag push → "v1.2.3", "1.2.3", "1.2", "1"
type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
Expand Down
126 changes: 126 additions & 0 deletions .github/workflows/docker-publish-fullstack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: Publish Full-Stack Docker Image to GHCR

on:
push:
branches: [main]
tags: ['v*']
pull_request:
branches: [main]
paths:
- 'Dockerfile.fullstack'
- 'Dockerfile.fullstack.dockerignore'
- 'docker-compose.fullstack.yml'
- '.github/workflows/docker-publish-fullstack.yml'
- 'package.json'
- 'package-lock.json'
- 'src/**'
- 'public/**'
- 'vite.config.ts'
- 'nginx.conf.template'
- 'server/**'
workflow_dispatch:

# A semver publication updates shared tags (for example 1 and 1.2), so tag
# releases use one group. Branches and pull requests remain independent.
concurrency:
group: fullstack-image-${{ github.ref_type == 'tag' && 'release' || github.ref }}
# Keep the newest branch/PR build, but finish every release tag in order so
# shared major/minor tags cannot race or leave an older version unpublished.
cancel-in-progress: ${{ github.ref_type != 'tag' }}

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/github-stars-manager-fullstack

jobs:
validate:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 30
# PR validation does not authenticate to GHCR and cannot publish packages.
permissions:
contents: read

steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

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

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

- name: Validate full-stack multi-architecture image
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
file: ./Dockerfile.fullstack
platforms: linux/amd64,linux/arm64
push: false
# The cache remains isolated from the frontend and backend image workflows.
cache-from: type=gha,scope=github-stars-manager-fullstack-pr,timeout=5m
cache-to: type=gha,scope=github-stars-manager-fullstack-pr,mode=max,timeout=5m,ignore-error=true

publish:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
# A cache or registry outage must not leave a publishing run blocked forever.
timeout-minutes: 30
permissions:
contents: read
packages: write
Comment thread
coderabbitai[bot] marked this conversation as resolved.

steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Verify release tag matches client version
if: github.ref_type == 'tag'
run: node scripts/check-release-version.cjs "$GITHUB_REF_NAME"

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

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

- name: Login to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
# branch push → "latest"
type=raw,value=latest,enable={{is_default_branch}}
# tag push → "v1.2.3", "1.2.3", "1.2", "1"
type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
# every build → sha-abc1234
type=sha,prefix=sha-

- name: Build and push Docker image
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
file: ./Dockerfile.fullstack
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# Keep this cache independent from frontend and server image builds.
cache-from: type=gha,scope=github-stars-manager-fullstack-publish-${{ github.ref_type }},timeout=5m
cache-to: type=gha,scope=github-stars-manager-fullstack-publish-${{ github.ref_type }},mode=max,timeout=5m,ignore-error=true
23 changes: 16 additions & 7 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish Docker Image to GHCR
name: Publish Backend Docker Image to GHCR

on:
push:
Expand All @@ -9,12 +9,14 @@ on:
# Keep only the newest run for each branch or tag, while allowing release tags
# and main to publish independently.
concurrency:
group: server-image-${{ github.ref }}
group: backend-image-${{ github.ref }}
cancel-in-progress: true

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/github-stars-manager-server
IMAGE_NAME: ${{ github.repository_owner }}/github-stars-manager-backend
# Compatibility alias used by the existing docker-compose.yml and direct users.
LEGACY_IMAGE_NAME: ${{ github.repository_owner }}/github-stars-manager-server

jobs:
build-and-push:
Expand All @@ -31,6 +33,10 @@ jobs:
with:
persist-credentials: false

- name: Verify release tag matches client version
if: github.ref_type == 'tag'
run: node scripts/check-release-version.cjs "$GITHUB_REF_NAME"

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

Expand All @@ -48,11 +54,14 @@ jobs:
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
images: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
${{ env.REGISTRY }}/${{ env.LEGACY_IMAGE_NAME }}
tags: |
# branch push → "latest"
type=raw,value=latest,enable={{is_default_branch}}
# tag push → "v1.2.3", "1.2.3", "1.2", "1"
type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
Expand All @@ -67,6 +76,6 @@ jobs:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# Do not share the default `buildkit` scope with the frontend image.
cache-from: type=gha,scope=github-stars-manager-server-${{ github.ref_type }},timeout=5m
cache-to: type=gha,scope=github-stars-manager-server-${{ github.ref_type }},mode=max,timeout=5m,ignore-error=true
# Do not share the default `buildkit` scope with frontend or full-stack images.
cache-from: type=gha,scope=github-stars-manager-backend-${{ github.ref_type }},timeout=5m
cache-to: type=gha,scope=github-stars-manager-backend-${{ github.ref_type }},mode=max,timeout=5m,ignore-error=true
Loading
Loading