From edf6df8577acd68894add348f1fb1c73a2c76814 Mon Sep 17 00:00:00 2001 From: ysyneu Date: Fri, 29 May 2026 10:04:21 +0800 Subject: [PATCH 1/3] feat: make installed binary name overridable via env/make var MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit install.sh: INSTALLED_NAME defaults to "flashduty" but honours a caller-supplied INSTALLED_NAME env var so we can install our bundled copy as "fduty" without shadowing a user's own flashduty installation. All uses of the installed name (mv target, chmod, PATH message, verify hint) already reference the variable — only the hardcoded default literal needed updating. Makefile: BINARY_NAME switches from := (immediate, non-overridable) to ?= so `make build BINARY_NAME=fduty` produces bin/fduty; default behaviour (make build) is unchanged. Public identity (cobra Use: string, help text, FLASHDUTY_* env vars, Go module, repo name) is untouched. --- Makefile | 2 +- install.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 802c720..cafcdf7 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # Build configuration -BINARY_NAME := flashduty +BINARY_NAME ?= flashduty BUILD_DIR := bin GOLANGCI_LINT_VERSION := v2.2.1 GOLANGCI_LINT := $(BUILD_DIR)/golangci-lint diff --git a/install.sh b/install.sh index 5476216..8632bca 100755 --- a/install.sh +++ b/install.sh @@ -15,7 +15,7 @@ set -e REPO="flashcatcloud/flashduty-cli" BINARY="flashduty-cli" -INSTALLED_NAME="flashduty" +INSTALLED_NAME="${INSTALLED_NAME:-flashduty}" INSTALL_DIR="${FLASHDUTY_INSTALL_DIR:-/usr/local/bin}" # When set, all release downloads are fetched from this prefix instead of github.com. @@ -188,7 +188,7 @@ main() { info " export PATH=\"${INSTALL_DIR}:\$PATH\"" ;; esac - info "Run 'flashduty version' to verify" + info "Run '${INSTALLED_NAME} version' to verify" } main From f05115f2857f381d2741ae9bd9a0dd5ed47c084b Mon Sep 17 00:00:00 2001 From: ysyneu Date: Fri, 29 May 2026 15:04:17 +0800 Subject: [PATCH 2/3] ci(release): mirror install.sh + install.ps1 to CDN on every release The release workflow uploaded binaries + releases/latest but not the install scripts; those were mirrored only by install-scripts.yml on install.sh/.ps1 changes. Re-upload them here so a release always ships a current installer on the CDN even when the scripts themselves didn't change. --- .github/workflows/release.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0e0021f..f8ef52b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,3 +97,16 @@ jobs: aws --endpoint-url="$ENDPOINT" s3 cp /tmp/latest "s3://${BUCKET}/${latest_key}" \ --cache-control "public, max-age=60" \ --content-type "text/plain; charset=utf-8" + + # Refresh the install scripts on every release so the mirror never + # ships a stale/missing installer (install-scripts.yml only fires when + # install.sh/.ps1 change on main; the scripts are version-agnostic, so + # re-uploading the current copy here is the belt-and-suspenders guarantee). + sh_key="${PREFIX:+${PREFIX}/}install.sh" + aws --endpoint-url="$ENDPOINT" s3 cp install.sh "s3://${BUCKET}/${sh_key}" \ + --cache-control "public, max-age=300" \ + --content-type "text/x-shellscript; charset=utf-8" + ps1_key="${PREFIX:+${PREFIX}/}install.ps1" + aws --endpoint-url="$ENDPOINT" s3 cp install.ps1 "s3://${BUCKET}/${ps1_key}" \ + --cache-control "public, max-age=300" \ + --content-type "text/plain; charset=utf-8" From f17e63a5a0017657fb4bc4f56e4ce5be64b5cc6f Mon Sep 17 00:00:00 2001 From: ysyneu Date: Fri, 29 May 2026 15:30:51 +0800 Subject: [PATCH 3/3] ci: bake CDN default MIRROR_URL into mirrored install.sh The copy served from the CDN now defaults MIRROR_URL to the CDN (injected at upload time via the new MIRROR_PUBLIC_URL secret), so `curl /install.sh | sh` pulls binaries from the CDN without the caller passing MIRROR_URL. The repo / GitHub copy stays generic (defaults to GitHub). A grep guard fails the job if the default line ever stops matching, so the injection can't silently no-op. --- .github/workflows/install-scripts.yml | 13 ++++++++++++- .github/workflows/release.yml | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/install-scripts.yml b/.github/workflows/install-scripts.yml index dc3375d..fbfa950 100644 --- a/.github/workflows/install-scripts.yml +++ b/.github/workflows/install-scripts.yml @@ -45,6 +45,7 @@ jobs: BUCKET: ${{ secrets.MIRROR_S3_BUCKET }} ENDPOINT: ${{ secrets.MIRROR_S3_ENDPOINT }} PREFIX: ${{ secrets.MIRROR_S3_PATH_PREFIX }} + MIRROR_PUBLIC_URL: ${{ secrets.MIRROR_PUBLIC_URL }} run: | set -eu if [ -z "${BUCKET:-}" ] || [ -z "${ENDPOINT:-}" ]; then @@ -59,8 +60,18 @@ jobs: aws configure set default.response_checksum_validation when_required PREFIX="${PREFIX#/}"; PREFIX="${PREFIX%/}" + # Bake the CDN as the default MIRROR_URL into the copy we serve from the + # CDN, so `curl /install.sh | sh` pulls binaries from the CDN with + # no MIRROR_URL arg. The repo / GitHub copy stays generic (GitHub default). + src_sh=install.sh + if [ -n "${MIRROR_PUBLIC_URL:-}" ]; then + pub="${MIRROR_PUBLIC_URL%/}${PREFIX:+/${PREFIX}}" + sed "s#MIRROR_URL=\"\${MIRROR_URL:-}\"#MIRROR_URL=\"\${MIRROR_URL:-${pub}}\"#" install.sh > /tmp/install.sh + grep -q "MIRROR_URL:-${pub}" /tmp/install.sh || { echo "ERROR: MIRROR_URL default not injected (install.sh default line changed?)" >&2; exit 1; } + src_sh=/tmp/install.sh + fi sh_key="${PREFIX:+${PREFIX}/}install.sh" - aws --endpoint-url="$ENDPOINT" s3 cp install.sh "s3://${BUCKET}/${sh_key}" \ + aws --endpoint-url="$ENDPOINT" s3 cp "$src_sh" "s3://${BUCKET}/${sh_key}" \ --cache-control "public, max-age=300" \ --content-type "text/x-shellscript; charset=utf-8" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f8ef52b..51ec805 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,6 +53,7 @@ jobs: BUCKET: ${{ secrets.MIRROR_S3_BUCKET }} ENDPOINT: ${{ secrets.MIRROR_S3_ENDPOINT }} PREFIX: ${{ secrets.MIRROR_S3_PATH_PREFIX }} + MIRROR_PUBLIC_URL: ${{ secrets.MIRROR_PUBLIC_URL }} VERSION: ${{ github.ref_name }} run: | set -eu @@ -102,8 +103,18 @@ jobs: # ships a stale/missing installer (install-scripts.yml only fires when # install.sh/.ps1 change on main; the scripts are version-agnostic, so # re-uploading the current copy here is the belt-and-suspenders guarantee). + # Bake the CDN as the default MIRROR_URL into the served copy so + # `curl /install.sh | sh` pulls binaries from the CDN with no + # MIRROR_URL arg. The repo / GitHub copy stays generic (GitHub default). + src_sh=install.sh + if [ -n "${MIRROR_PUBLIC_URL:-}" ]; then + pub="${MIRROR_PUBLIC_URL%/}${PREFIX:+/${PREFIX}}" + sed "s#MIRROR_URL=\"\${MIRROR_URL:-}\"#MIRROR_URL=\"\${MIRROR_URL:-${pub}}\"#" install.sh > /tmp/install.sh + grep -q "MIRROR_URL:-${pub}" /tmp/install.sh || { echo "ERROR: MIRROR_URL default not injected (install.sh default line changed?)" >&2; exit 1; } + src_sh=/tmp/install.sh + fi sh_key="${PREFIX:+${PREFIX}/}install.sh" - aws --endpoint-url="$ENDPOINT" s3 cp install.sh "s3://${BUCKET}/${sh_key}" \ + aws --endpoint-url="$ENDPOINT" s3 cp "$src_sh" "s3://${BUCKET}/${sh_key}" \ --cache-control "public, max-age=300" \ --content-type "text/x-shellscript; charset=utf-8" ps1_key="${PREFIX:+${PREFIX}/}install.ps1"