mirror of
https://github.com/sendevia/website.git
synced 2026-03-06 15:42:34 +08:00
Compare commits
17 Commits
2bc889a388
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 206cf373a3 | |||
| 9677ac1367 | |||
| b41cea0bed | |||
| 8345515977 | |||
| dd069771a8 | |||
| e4217512aa | |||
| 93a42ec037 | |||
| d489bf24c4 | |||
| 67a26def4f | |||
| a7e0528c24 | |||
| 29885ae607 | |||
| dabb2f6164 | |||
| 1247943a5e | |||
| b822fe6227 | |||
| f01232241f | |||
| c8b917bda5 | |||
| aa3cdbc695 |
65
.github/workflows/docker-build.yml
vendored
Normal file
65
.github/workflows/docker-build.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- "package.json"
|
||||
- "Dockerfile"
|
||||
- ".github/workflows/docker-build.yml"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Extract version from package.json
|
||||
id: version
|
||||
run: |
|
||||
VERSION=$(grep '"version"' package.json | sed 's/.*"\([^"]*\)".*/\1/' | sed 's/(.*)//g')
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/website
|
||||
ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=raw,value=${{ steps.version.outputs.version }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
no-cache: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,3 +5,5 @@ node_modules
|
||||
package-lock.json
|
||||
cache/
|
||||
dist/
|
||||
.agents
|
||||
nginx-config.conf
|
||||
|
||||
@@ -28,7 +28,7 @@ const siteVersion = theme.value.siteVersion;
|
||||
</div>
|
||||
<div class="beian-info">
|
||||
<div>
|
||||
<a href="https://beian.miit.gov.cn/" target="_blank">黑ICP备2024016516号-1</a>
|
||||
<a href="https://beian.miit.gov.cn/" target="_blank">黑ICP备2024016516号</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -174,7 +174,9 @@ if (isClient()) {
|
||||
<template>
|
||||
<nav class="NavBar" :class="navClass">
|
||||
<div class="fab-container">
|
||||
<MaterialButton color="text" :icon="navStateStore.isNavExpanded ? 'menu_open' : 'menu'" @click="toggleNav" />
|
||||
<ClientOnly>
|
||||
<MaterialButton color="text" :icon="navStateStore.isNavExpanded ? 'menu_open' : 'menu'" @click="toggleNav" />
|
||||
</ClientOnly>
|
||||
<button class="fab" @mousedown.prevent @click.stop="toggleSearch">
|
||||
<span>{{ searchStateStore.isSearchActive ? "close" : "search" }}</span>
|
||||
<p :ref="(el) => setLabelRef(el, '.fab')">搜索</p>
|
||||
@@ -202,15 +204,17 @@ if (isClient()) {
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<MaterialButton
|
||||
class="theme-btn"
|
||||
size="m"
|
||||
color="text"
|
||||
:title="themeStateStore.currentLabel"
|
||||
:icon="themeStateStore.currentIcon"
|
||||
@click="toggleTheme"
|
||||
>
|
||||
</MaterialButton>
|
||||
<ClientOnly>
|
||||
<MaterialButton
|
||||
class="theme-btn"
|
||||
size="m"
|
||||
color="text"
|
||||
:title="themeStateStore.currentLabel"
|
||||
:icon="themeStateStore.currentIcon"
|
||||
@click="toggleTheme"
|
||||
>
|
||||
</MaterialButton>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
@@ -48,11 +48,21 @@ const copyShortLink = async () => {
|
||||
const collectHeadings = () => {
|
||||
if (!isClient()) return;
|
||||
const nodes = Array.from(document.querySelectorAll("h1[id], h2[id]")) as HTMLElement[];
|
||||
headings.value = nodes.map((n) => ({
|
||||
id: n.id,
|
||||
text: n.textContent?.trim() || n.id,
|
||||
level: +n.tagName.replace("H", ""),
|
||||
}));
|
||||
|
||||
headings.value = nodes.map((n) => {
|
||||
// 克隆节点并移除行内锚点
|
||||
const clone = n.cloneNode(true) as HTMLElement;
|
||||
const inlineAnchors = Array.from(clone.querySelectorAll(".AnchorLink.inline")) as HTMLElement[];
|
||||
inlineAnchors.forEach((el) => el.remove());
|
||||
|
||||
const text = clone.textContent?.trim() || n.id;
|
||||
|
||||
return {
|
||||
id: n.id,
|
||||
text,
|
||||
level: +n.tagName.replace("H", ""),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/** 更新指示器(高亮边框)的位置和尺寸 */
|
||||
|
||||
@@ -142,15 +142,15 @@ if (isClient()) {
|
||||
<PrevNext />
|
||||
</main>
|
||||
<aside id="article-aside">
|
||||
<div class="post-info">
|
||||
<p v-if="frontmatter.description" class="description">{{ frontmatter.description }}</p>
|
||||
<p v-if="formattedPublishDate" class="date-publish">发布于 {{ formattedPublishDate }}</p>
|
||||
<ClientOnly>
|
||||
<ClientOnly>
|
||||
<div class="post-info">
|
||||
<p v-if="frontmatter.description" class="description">{{ frontmatter.description }}</p>
|
||||
<p v-if="formattedPublishDate" class="date-publish">发布于 {{ formattedPublishDate }}</p>
|
||||
<p v-if="formattedLastUpdated" :title="lastUpdatedRawTime" class="date-update">
|
||||
{{ formattedLastUpdated }}
|
||||
</p>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</div>
|
||||
</ClientOnly>
|
||||
<ButtonGroup v-if="frontmatter?.external_links" :links="frontmatter.external_links" size="m" layout="vertical" />
|
||||
<PageIndicator />
|
||||
</aside>
|
||||
|
||||
37
Caddyfile
Normal file
37
Caddyfile
Normal file
@@ -0,0 +1,37 @@
|
||||
:80 {
|
||||
# 根目录指向构建产物
|
||||
root * /app
|
||||
|
||||
# 关闭访问日志
|
||||
log {
|
||||
output discard
|
||||
}
|
||||
|
||||
# 启用压缩
|
||||
encode gzip zstd
|
||||
|
||||
# 文件服务器配置
|
||||
try_files {path} {path}.html {path}/
|
||||
file_server
|
||||
|
||||
# 错误页面处理
|
||||
handle_errors {
|
||||
@404 {
|
||||
expression {http.error.status_code} == 404
|
||||
}
|
||||
@403 {
|
||||
expression {http.error.status_code} == 403
|
||||
}
|
||||
rewrite @404 /404.html
|
||||
rewrite @403 /404.html
|
||||
file_server
|
||||
}
|
||||
|
||||
# 静态资源缓存配置
|
||||
@assets {
|
||||
path /assets/*
|
||||
}
|
||||
header @assets {
|
||||
Cache-Control "public, immutable, max-age=31536000"
|
||||
}
|
||||
}
|
||||
27
Dockerfile
Normal file
27
Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
||||
# 构建阶段
|
||||
FROM node:trixie-slim AS builder
|
||||
|
||||
# 安装 git
|
||||
RUN apt-get update && apt-get install -y git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 拉取项目代码
|
||||
RUN git clone https://github.com/sendevia/website . --depth=1
|
||||
|
||||
# 安装依赖并构建
|
||||
RUN npm i && npm run docs:build
|
||||
|
||||
# 最终阶段
|
||||
FROM caddy:alpine AS final
|
||||
|
||||
# 从构建阶段复制 dist 产物到工作目录
|
||||
COPY --from=builder /app/.vitepress/dist /app
|
||||
|
||||
# 复制Caddyfile配置文件
|
||||
COPY Caddyfile /etc/caddy/Caddyfile
|
||||
|
||||
# 启动Caddy服务器
|
||||
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "26.3.4(308)",
|
||||
"version": "26.3.5(323)",
|
||||
"scripts": {
|
||||
"update-version": "bash ./scripts/update-version.sh",
|
||||
"docs:dev": "vitepress dev",
|
||||
|
||||
Reference in New Issue
Block a user