一键部署到 CloudFlare Pages、Vercel、Netlify 等平台的脚本
Makefile
构建相关命令:
start 启动开发服务器,默认端口为 3000
build 构建项目并压缩静态文件
clean 删除 public 目录
文章管理命令:
drafts 列出所有草稿文件
undraft 将所有草稿状态从 true 改为 false
update-date 根据内容更新被修改和新增文章的 lastmod 时间为当前时间
部署相关命令:
deploy 部署到指定平台(通过 PLATFORM 变量指定)
deploy-framagit 部署到 Framagit
deploy-fermyon 部署到 Fermyon
deploy-surge 部署到 Surge
deploy-vercel 部署到 Vercel
deploy-netlify 部署到 Netlify
deploy-fleek 部署到 Fleek
deploy-deno 部署到 Deno Deploy
deploy-cloudflare 部署到 CloudFlare Pages
deploy-all 部署到所有平台(排除 Framagit)
port = 3000
# Surge 项目名称
SURGE_PROJECT = jetsung
# Cloudflare 项目名称
CLOUDFLARE_PROJECT = jetsung
# Vercel 项目名称
VERCEL_SCOPE = idevsig
VERCEL_PROJECT = jetsung
# Netlify 项目名称
NETLIFY_PROJECT = jetsung
# Fleek 项目名称
FLEEK_PROJECT = jetsung
# Deno 项目名称
DENO_PROJECT=jetsung
# 定义 sed 命令(兼容 macOS 和 Linux)
SED_INPLACE = sed -i
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
SED_INPLACE = sed -i ""
endif
# 定义获取文件修改时间的命令
ifeq ($(UNAME_S),Linux)
GET_MODTIME = date -Iseconds -d @$$(stat -c %Y "$$file")
else
GET_MODTIME = date -Iseconds -r "$$file"
endif
# 构建 Hugo 项目
build-hugo:
@echo "Building Hugo project..."
hugo -D --minify
# 生成 version.txt 文件
generate-version:
@echo "Generating version.txt..."
@mkdir -p public # 确保 public 目录存在
@echo "Commit SHA: $$(git rev-parse HEAD)" > public/version.txt
@echo "Commit author: $$(git log -1 --pretty=format:'%an <%ae>')" >> public/version.txt
@echo "Commit timestamp: $$(git log -1 --pretty=format:'%cd' --date=iso)" >> public/version.txt
@echo "version.txt generated successfully!"
@cat public/version.txt # 打印文件内容以验证
# 构建相关
.PHONY: start build clean
## 启动
start: ## 启动开发服务器,默认端口为 3000
hugo server -D -p "$(port)"
# 构建项目
build: build-hugo generate-version ## 构建项目并压缩静态文件
@echo "Build complete!"
## 清理生成的文件
clean: ## 删除 public 目录
@echo "Removing public directory"
rm -rf public
# 文章相关
.PHONY: undraft update-date
## 列出所有草稿文件
drafts: ## 列出所有草稿文件
@find content -name "*.md" -type f -exec grep -l 'draft: true' {} \;
## 将所有草稿修改成非草稿
undraft: ## 将所有草稿状态从 true 改为 false
@echo "Modifying draft from true to false"
@find content -name "*.md" -type f -exec sed -i 's/draft: true/draft: false/g' {} +
## 更新文章的修改时间
update-date: ## 根据内容更新被修改和新增文章的 lastmod 时间为当前时间
@echo "Updating lastmod for modified and new files based on content changes"
@git status --porcelain | awk '/^[ M]/ {print $$2} /^[ A]/ {print $$2}' | uniq | grep '^content/' | grep '\.md$$' | while read -r file; do \
if git diff --quiet -- "$$file"; then \
echo "No content changes for: $$file"; \
else \
modtime=$$($(GET_MODTIME)); \
if ! grep -q "lastmod: $$modtime" "$$file"; then \
$(SED_INPLACE) "s/lastmod: .*/lastmod: $$modtime/g" "$$file"; \
echo "Updated lastmod $$modtime for: $$file"; \
else \
echo "No changes needed for: $$file"; \
fi; \
fi; \
done
# 部署相关
.PHONY: deploy
## 部署到对应平台
deploy: deploy-$(PLATFORM) ## 部署到指定平台(通过 PLATFORM 变量指定)
## 部署到 Framagit (Git Pages)
deploy-framagit: ## 部署到 Framagit
@echo "Deploying to Framagit"
git push origin main
## 部署到 Fermyon (wasm)
## https://developer.fermyon.com/spin/v3/build#setting-up-for-spin-build
deploy-fermyon: ## 部署到 Fermyon
@echo "Deploying to Fermyon"
cd app && \
spin build && \
spin deploy
## 部署到 Surge
## https://surge.sh/help/getting-started-with-surge
deploy-surge: ## 部署到 Surge
@echo "Deploying to Surge"
surge ./public/ "https://$(SURGE_PROJECT).surge.sh"
## 部署到 Vercel
## https://vercel.com/docs/getting-started-with-vercel
deploy-vercel: ## 部署到 Vercel
@echo "Deploying to Vercel"
cd ./public && \
vercel link --scope "$(VERCEL_SCOPE)" --project "$(VERCEL_PROJECT)" --yes && \
vercel --prod --yes
## 部署到 Netlify
## https://docs.netlify.com/cli/get-started/
deploy-netlify: ## 部署到 Netlify
@echo "Deploying to Netlify"
cd public && \
netlify deploy --dir . --site "$(NETLIFY_PROJECT)" --prod
## 部署到 Fleek
## https://fleek.xyz/docs/cli/
deploy-fleek: ## 部署到 Fleek
@echo "Deploying to Fleek"
@if [ -z "$(FLEEK_PROJECT_ID)" ]; then \
export FLEEK_PROJECT_ID=$$(fleek projects list | sed -n '4p' | awk '{print $$1}'); \
fi
cd public && \
printf '{"sites":[{"slug":"%s","distDir":"."}]}' "$(FLEEK_PROJECT)" > fleek.config.json && \
fleek sites deploy && \
rm fleek.config.json
## 部署到 Deno Deploy
## https://docs.deno.com/deploy/manual/
deploy-deno: ## 部署到 Deno Deploy
@echo "Deploying to Deno Deploy"
cd public && \
deployctl deploy --project="$(DENO_PROJECT)" --prod "https://deno.land/std@0.224.0/http/file_server.ts" && \
rm deno.json
## 部署到 CloudFlare Pages
deploy-cloudflare: ## 部署到 CloudFlare Pages
@echo "Deploying to CloudFlare Pages"
wrangler pages deploy ./public/ --project-name "$(CLOUDFLARE_PROJECT)"
.PHONY: deploy-all
## 部署到所有平台
deploy-all: build deploy-fermyon deploy-surge deploy-cloudflare deploy-vercel deploy-netlify ## 部署到所有平台(排除 Framagit)
@echo "All deployments completed!"
# 帮助信息
.DEFAULT_GOAL := help
.PHONY: help
help:
@echo "\n构建相关命令:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
| grep -E '^(build|clean|start|generate-version):' \
| awk 'BEGIN {FS = ":.*?## "} {printf "$(HELP_COLOR)%-20s$(NC) %s\n", $$1, $$2}'
@echo "\n文章管理命令:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
| grep -E '^(drafts|undraft|update-date):' \
| awk 'BEGIN {FS = ":.*?## "} {printf "$(HELP_COLOR)%-20s$(NC) %s\n", $$1, $$2}'
@echo "\n部署相关命令:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
| grep -E '^(deploy|deploy-[a-zA-Z_-]+|deploy-all):' \
| awk 'BEGIN {FS = ":.*?## "} {printf "$(HELP_COLOR)%-20s$(NC) %s\n", $$1, $$2}'
gitlab-ci.yml
---
image : registry.gitlab.com/pages/hugo/hugo_extended:latest
variables :
GIT_DEPTH: 0
GIT_STRATEGY: clone
GIT_SUBMODULE_STRATEGY: recursive
TZ: Asia/Shanghai
stages :
- build
- deploy
cache :
paths:
- public/
before_script : |
apk update
apk add --no-cache build-base bash nodejs npm curl
make --version
node -v
npm -v
# Build Hugo site
build :
stage: build
script:
- hugo --minify
- |
cat > public/version.txt <<EOF
Commit SHA: $CI_COMMIT_SHA
Commit author: $CI_COMMIT_AUTHOR
Commit timestamp: $CI_COMMIT_TIMESTAMP
EOF
artifacts:
paths:
- public/
# Deploy to Framagit Pages
pages :
stage: deploy
dependencies:
- build
script:
- echo "Deploying to Framagit Pages..."
# 这里可以添加部署到 Framagit Pages 的逻辑
artifacts:
paths:
- public/
only:
- deploy
# Deploy to Surge
deploy-surge :
stage: deploy
script:
- |
npm install -g surge
surge --version
cp -r ./public /blog
cd /blog
- surge . "https://${SURGE_PROJECT}.surge.sh" --token "${SURGE_TOKEN}"
only:
- deploy
# Deploy to Fermyon (wasm)
deploy-fermyon :
stage: deploy
image: rust:latest
dependencies:
- build
before_script:
- |
curl -fsSL https://developer.fermyon.com/downloads/install.sh | bash
mv spin /usr/local/bin/
spin --version
script:
- |
mkdir /blog
cp -r ./public /blog/
cp -r ./app /blog/
- |
cd app
spin build
spin deploy
only:
- deploy
# Deploy to Vercel
deploy-vercel :
stage: deploy
script:
- |
npm install -g vercel
vercel --version
cp -r ./public /blog
cd /blog
- |
vercel link --scope "${VERCEL_SCOPE}" --project "${VERCEL_PROJECT}" --yes --token "${VERCEL_TOKEN}"
vercel --prod --yes --token "${VERCEL_TOKEN}"
only:
- deploy
# Deploy to Netlify
deploy-netlify :
stage: deploy
script:
- |
npm install -g netlify-cli
netlify --version
cp -r ./public /blog
cd /blog
- |
netlify deploy --dir . --site "${NETLIFY_SITE}" --prod --auth "${NETLIFY_TOKEN}"
only:
- deploy
# Deploy to Fleek
## FLEEK_TOKEN, FLEEK_PROJECT_ID, FLEEK_PROJECT (slug)
deploy-fleek :
stage: deploy
script:
- |
npm install -g @fleek-platform/cli
fleek --version
cp -r ./public /blog
cd /blog
- |
if [ -z "${FLEEK_PROJECT_ID}" ]; then
export FLEEK_PROJECT_ID=$(fleek projects list | sed -n '4p' | awk '{print $1}')
fi
- |
printf '{"sites":[{"slug":"%s","distDir":"."}]}' "${FLEEK_PROJECT}" > fleek.config.json
fleek sites deploy
only:
- deploy
# Deploy to Deno
## DENO_DEPLOY_TOKEN, DENO_PROJECT (slug)
deploy-deno :
stage: deploy
image: denoland/deno:alpine
before_script:
- |
deno install -A jsr:@deno/deployctl --global
deno --version
deployctl --version
script:
- |
cp -r ./public /blog
cd /blog
- |
deployctl deploy --project="${DENO_PROJECT}" --prod "https://deno.land/std@0.224.0/http/file_server.ts"
only:
- deploy
# Deploy to Cloudflare Pages
deploy-cloudflare:
stage: deploy
dependencies:
- build
script:
- |
npm install -g wrangler
wrangler --version
cp -r ./public /blog
cd /blog
- |
wrangler pages deploy . --project-name "${CLOUDFLARE_PROJECT}"
only:
- main