diff --git a/.github/workflows/clean-site.yml b/.github/workflows/clean-site.yml
new file mode 100644
index 000000000..cf3b8b4ed
--- /dev/null
+++ b/.github/workflows/clean-site.yml
@@ -0,0 +1,121 @@
+name: Cleanup iotdb-website Repository
+
+on:
+ workflow_dispatch:
+ inputs:
+ target_branch:
+ description: 'Branch to cleanup (asf-site or asf-staging)'
+ required: true
+ type: choice
+ options:
+ - asf-site
+ - asf-staging
+ - both
+ confirm:
+ description: 'Type "CONFIRM" to proceed with cleanup'
+ required: true
+ type: string
+
+jobs:
+ cleanup:
+ runs-on: ubuntu-latest
+ if: github.event.inputs.confirm == 'CONFIRM'
+
+ steps:
+ - name: Validate confirmation
+ if: github.event.inputs.confirm != 'CONFIRM'
+ run: |
+ echo "❌ Cleanup cancelled: confirmation not provided"
+ exit 1
+
+ - name: Checkout iotdb-website repository
+ uses: actions/checkout@v4
+ with:
+ repository: apache/iotdb-website
+ token: ${{ secrets.IOTDB_WEBSITE_BUILD }}
+ fetch-depth: 0
+ ref: ${{ github.event.inputs.target_branch == 'both' && 'asf-site' || github.event.inputs.target_branch }}
+
+ - name: Configure Git
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply. github.com"
+
+ - name: Cleanup asf-site branch
+ if: github.event. inputs.target_branch == 'asf-site' || github.event.inputs.target_branch == 'both'
+ run: |
+ echo "🧹 Cleaning up asf-site branch..."
+
+ # Checkout the branch
+ git checkout asf-site
+
+ # Create a new orphan branch (no history)
+ git checkout --orphan asf-site-new
+
+ # Add all current files
+ git add -A
+
+ # Create initial commit
+ git commit -m "chore: reset repository history to reduce size
+
+ Previous repository size: ~5.9GB
+ This commit resets the Git history to start fresh.
+
+ Ref: Repository cleanup initiative"
+
+ # Delete old branch and rename new one
+ git branch -D asf-site || true
+ git branch -m asf-site
+
+ # Force push (this removes all history)
+ git push -f origin asf-site
+
+ echo "✅ asf-site branch cleaned successfully"
+
+ - name: Cleanup asf-staging branch
+ if: github.event.inputs.target_branch == 'asf-staging' || github.event.inputs.target_branch == 'both'
+ run: |
+ echo "🧹 Cleaning up asf-staging branch..."
+
+ # Fetch and checkout the staging branch
+ git fetch origin asf-staging: asf-staging
+ git checkout asf-staging
+
+ # Create a new orphan branch (no history)
+ git checkout --orphan asf-staging-new
+
+ # Add all current files
+ git add -A
+
+ # Create initial commit
+ git commit -m "chore: reset repository history to reduce size
+
+ Previous repository size: ~5.9GB
+ This commit resets the Git history to start fresh.
+
+ Ref: Repository cleanup initiative"
+
+ # Delete old branch and rename new one
+ git branch -D asf-staging || true
+ git branch -m asf-staging
+
+ # Force push (this removes all history)
+ git push -f origin asf-staging
+
+ echo "✅ asf-staging branch cleaned successfully"
+
+ - name: Summary
+ run: |
+ echo "## Cleanup Summary" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ Successfully cleaned branch(es): **${{ github.event.inputs.target_branch }}**" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Next Steps" >> $GITHUB_STEP_SUMMARY
+ echo "1. Wait for GitHub to run garbage collection (may take hours)" >> $GITHUB_STEP_SUMMARY
+ echo "2. Check repository size at: https://github.com/apache/iotdb-website" >> $GITHUB_STEP_SUMMARY
+ echo "3. All users should re-clone the repository to get the cleaned version" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ⚠️ Important Notes" >> $GITHUB_STEP_SUMMARY
+ echo "- All commit history in the cleaned branch(es) has been removed" >> $GITHUB_STEP_SUMMARY
+ echo "- The repository size reduction may take some time to reflect on GitHub" >> $GITHUB_STEP_SUMMARY
+ echo "- Current deployments are not affected and will continue to work" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/site-build.yaml b/.github/workflows/site-build.yaml
index 9b27734b9..688deab60 100644
--- a/.github/workflows/site-build.yaml
+++ b/.github/workflows/site-build.yaml
@@ -37,7 +37,16 @@ jobs:
env:
NODE_OPTIONS: --max_old_space_size=8192
run: pnpm build
-
+
+ - name: Deploy staging website
+ env:
+ IOTDB_WEBSITE_BUILD: ${{ secrets.IOTDB_WEBSITE_BUILD }}
+ run: |
+ git config --global url."https://asf-ci-deploy:$IOTDB_WEBSITE_BUILD@github.com/apache/".insteadOf "https://github.com/apache/"
+ git config --global user.name github-actions
+ git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
+ npm run deploy:staging
+
linksCheck:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
@@ -59,7 +68,7 @@ jobs:
- name: Test build website
env:
NODE_OPTIONS: --max_old_space_size=8192
- run: pnpm run check-links
+ run: pnpm run check-links
deploy:
runs-on: ubuntu-latest
diff --git a/deploy.cjs b/deploy.cjs
index 80e13b1a2..44786a254 100644
--- a/deploy.cjs
+++ b/deploy.cjs
@@ -25,6 +25,7 @@ ghpages.publish(
repo: 'https://github.com/apache/iotdb-website.git',
message: 'Site checkin for project iotdb-website',
dotfiles: true,
+ history: false,
},
(err) => {
if (err instanceof Error) {
diff --git a/deploy_staging.cjs b/deploy_staging.cjs
index 3a800399d..15a0a6f5a 100644
--- a/deploy_staging.cjs
+++ b/deploy_staging.cjs
@@ -25,6 +25,7 @@ ghpages.publish(
repo: 'https://github.com/apache/iotdb-website.git',
message: 'Site checkin for project iotdb-website',
dotfiles: true,
+ history: false,
},
(err) => {
if (err instanceof Error) {
diff --git a/src/.vuepress/client.ts b/src/.vuepress/client.ts
index 9349d09b5..69dd8a27d 100644
--- a/src/.vuepress/client.ts
+++ b/src/.vuepress/client.ts
@@ -26,12 +26,14 @@ import {
} from 'vuepress/client';
import useLegacyRoute from './composables/useLegacyRoute.js';
import DocSearch from './components/DocSearch.vue';
+import AIButton from './components/AIButton.vue';
import Layout from './components/SidebarLayout.vue';
import { getDocVersion } from './utils/index.js';
export default defineClientConfig({
enhance: ({ app }) => {
app.component('DocSearch', DocSearch);
+ app.component('AIButton', AIButton);
},
setup() {
useLegacyRoute();
diff --git a/src/.vuepress/components/AIButton.vue b/src/.vuepress/components/AIButton.vue
new file mode 100644
index 000000000..aa0ce1a10
--- /dev/null
+++ b/src/.vuepress/components/AIButton.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/.vuepress/config.ts b/src/.vuepress/config.ts
index 4184bccbf..c65c3a8e7 100644
--- a/src/.vuepress/config.ts
+++ b/src/.vuepress/config.ts
@@ -84,47 +84,43 @@ _paq.push(['enableLinkTracking']);
})();
`,
],
- // [
- // 'script',
- // {
- // async: true,
- // src: 'https://widget.kapa.ai/kapa-widget.bundle.js',
- // 'data-website-id': '2d37bfdd-8d98-40ba-9223-9d4f81bfb327',
- // // 'data-language': 'zh',
- // 'data-project-name': 'Apache IoTDB',
- // 'data-project-color': '#9E2878',
- // 'data-button-image-height': '0px',
- // 'data-button-image-width': '0px',
- // // 'data-button-bg-color': '#FFF',
- // // 'data-button-text-color': '#9E2878',
- // 'data-project-logo': 'https://iotdb.apache.org/slogo.png',
- // 'data-button-position-right': '16px',
- // 'data-button-position-bottom': '120px',
- // 'data-button-height': '50px',
- // 'data-button-width': '50px',
- // 'data-button-text': 'Ask',
- // 'data-modal-image-width': '150px',
- // 'data-modal-title': 'AI Docs',
- // // 'data-modal-disclaimer':
- // // 'This is a custom LLM with access to all [Kapa documentation](https://docs.kapa.ai).',
- // // 'data-modal-example-questions':
- // // 'How do I get started?,How to add example questions?',
- // 'data-user-analytics-fingerprint-enabled': 'true',
- // // 'data-modal-x-offset': '0',
- // // 'data-modal-y-offset': '0',
- // // 'data-modal-with-overlay': 'false',
- // // 'data-modal-inner-flex-direction': 'column',
- // // 'data-modal-inner-justify-content': 'end',
- // // 'data-modal-inner-max-width': '500px',
- // // 'data-modal-inner-position-left': 'auto',
- // // 'data-modal-inner-position-right': '0',
- // // 'data-modal-inner-position-bottom': '0',
- // // 'data-modal-inner-position-top': '0',
- // // 'data-modal-size': '100vh',
- // // 'data-modal-lock-scroll': 'false',
- // // 'data-modal-header-bg-color': '#fff',
- // },
- // ],
+ [
+ 'script',
+ {
+ async: true,
+ src: 'https://widget.kapa.ai/kapa-widget.bundle.js',
+ 'data-website-id': '2d37bfdd-8d98-40ba-9223-9d4f81bfb327',
+ // 'data-language': 'zh',
+ 'data-project-name': 'Apache IoTDB',
+ 'data-project-color': '#FFFFFF',
+ 'data-button-z-index': '1999',
+ 'data-button-padding': '4px',
+ 'data-button-border-radius': '4px',
+ 'data-button-image-height': '24px',
+ 'data-button-image-width': '20px',
+ 'data-button-text-color': '#9E2878',
+ 'data-project-logo': 'https://iotdb.apache.org/img/logo.svg',
+ 'data-button-position-right': '16px',
+ 'data-button-position-bottom': '8px',
+ 'data-button-height': '56px',
+ 'data-button-width': '48px',
+ 'data-button-text': 'Ask',
+ // 'data-button-hide': 'true',
+ 'data-modal-override-open-selector': '#custom-ask-ai-button',
+ 'data-modal-image-width': '150px',
+ 'data-modal-title': 'AI Docs',
+ 'data-modal-title-color': '#9E2878',
+ 'data-modal-disclaimer':
+ 'This is a custom LLM for Apache IoTDB with access to all [documentation](iotdb.apache.org/docs/), [GitHub Open Issues, PRs and READMEs](github.com/apache/iotdb).
Companies deploy assistants like this ([built by kapa.ai](https://kapa.ai)) on docs via [website widget](https://docs.kapa.ai/integrations/website-widget) (Docker, Reddit), in [support forms](https://docs.kapa.ai/integrations/support-form-deflector) for ticket deflection (Monday.com, Mapbox), or as [Slack bots](https://docs.kapa.ai/integrations/slack-bot) with private sources.',
+
+ // 'data-modal-example-questions':
+ // 'How do I get started?,How to add example questions?',
+ 'data-user-analytics-fingerprint-enabled': 'true',
+ 'data-consent-required': 'true',
+ 'data-consent-screen-disclaimer':
+ "By clicking , you consent to the use of the AI assistant in accordance with kapa.ai's [Privacy Policy](https://www.kapa.ai/content/privacy-policy). This service uses reCAPTCHA, which requires your consent to Google's [Privacy Policy](https://policies.google.com/privacy) and [Terms of Service](https://policies.google.com/terms). By proceeding, you explicitly agree to both kapa.ai's and Google's privacy policies.",
+ },
+ ],
],
shouldPrefetch: false,
diff --git a/src/.vuepress/public/.asf.yaml b/src/.vuepress/public/.asf.yaml
index b1a8a5258..dd94db902 100644
--- a/src/.vuepress/public/.asf.yaml
+++ b/src/.vuepress/public/.asf.yaml
@@ -20,6 +20,7 @@
staging:
profile: ~
whoami: asf-staging
+ autostage: "*"
publish:
whoami: asf-site
diff --git a/src/.vuepress/public/.htaccess b/src/.vuepress/public/.htaccess
index b6c11b983..ec9fa3251 100644
--- a/src/.vuepress/public/.htaccess
+++ b/src/.vuepress/public/.htaccess
@@ -6,4 +6,4 @@ RewriteRule . /404.html [L]
ErrorDocument 404 /404.html
-Header set Content-Security-Policy "default-src data: blob: 'self' *.apache.org *.githubusercontent.com *.github.com *.algolia.net *.algolianet.com *.kapa.ai www.google.com *.gstatic.com *.apachecon.com *.communityovercode.org 'unsafe-inline' 'unsafe-eval'; frame-src 'self' www.google.com data: blob:; frame-ancestors 'self'; worker-src 'self' data: blob:; img-src 'self' blob: data: https: *.apache.org www.apachecon.com; style-src 'self' 'unsafe-inline' data:;"
\ No newline at end of file
+Header set Content-Security-Policy "default-src data: blob: 'self' *.apache.org *.kapa.ai *.githubusercontent.com *.googleapis.com *.google.com *.run.app *.gstatic.com *.github.com https://hcaptcha.com https://*.hcaptcha.com *.algolia.net *.algolianet.com *.apachecon.com *.communityovercode.org 'unsafe-inline' 'unsafe-eval'; frame-src *; frame-ancestors 'self' *.google.com; worker-src 'self' data: blob:; img-src 'self' blob: data: https:; font-src 'self' data: blob:; object-src 'none'"
diff --git a/src/.vuepress/styles/index.scss b/src/.vuepress/styles/index.scss
index 48914a97e..4e1531e1e 100644
--- a/src/.vuepress/styles/index.scss
+++ b/src/.vuepress/styles/index.scss
@@ -190,4 +190,8 @@ div[class*='language-'] pre code {
.vp-project-home .vp-hero-info-wrapper:not(.fullscreen) .vp-hero-info {
max-width: 100% !important;
+}
+.vp-back-to-top-button {
+ transform: none !important;
+ bottom: 4.5rem;
}
\ No newline at end of file
diff --git a/src/.vuepress/theme.ts b/src/.vuepress/theme.ts
index 1560344f8..83e00d9ea 100644
--- a/src/.vuepress/theme.ts
+++ b/src/.vuepress/theme.ts
@@ -38,7 +38,7 @@ export default hopeTheme(
navbarLayout: {
start: ['Brand'],
center: [],
- end: ['DocSearch', 'Links', 'Language', 'Outlook', 'Repo'],
+ end: ['DocSearch', 'AIButton', 'Links', 'Language', 'Outlook', 'Repo'],
},
toc: {
levels: [2, 3],