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],