diff --git a/.github/workflows/publish_configs.yml b/.github/workflows/publish_configs.yml new file mode 100644 index 00000000..d97c2119 --- /dev/null +++ b/.github/workflows/publish_configs.yml @@ -0,0 +1,34 @@ +# publish public configs to OSS +name: publish_configs + +on: + push: + branches: + - "master" + pull_request: + branches: + - "master" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v2 + + - name: Setup Node.js + uses: actions/setup-node@v3 + + - name: Build + run: node scripts/test_configs.js + + - name: Publish to OSS + if: ${{ github.event_name == 'push' }} + uses: tvrcgo/oss-action@master + with: + key-id: ${{ secrets.OSS_ACCESS_KEY_ID }} + key-secret: ${{ secrets.OSS_ACCESS_KEY_SECRET }} + region: ${{ secrets.OSS_REGION }} + bucket: ${{ secrets.OSS_BUCKET }} + assets: | + ./public_configs/**:${{ secrets.OSS_TARGET_PATH }} diff --git a/public_configs/fast-pr-url-rules.js b/public_configs/fast-pr-url-rules.js new file mode 100644 index 00000000..8c33e537 --- /dev/null +++ b/public_configs/fast-pr-url-rules.js @@ -0,0 +1,162 @@ +// remote-code.js +export const urlRules = [ + { + domains: ['open-digger.cn', 'open-digger'], + ruleFunction: (url) => { + const baseUrl = 'https://open-digger.cn/'; + const repoName = 'X-lab2017/open-digger-website'; + const branch = 'master'; + const platform = 'Github'; + let filePath = ''; + if (!url.startsWith(baseUrl)) return null; + let i18n = null; + let docPath = url.replace(baseUrl, '').split('#')[0]; + for (const l of ['en/', 'fr/']) { + if (docPath.startsWith(l)) { + i18n = l; + docPath = docPath.substring(l.length); + break; + } + } + if (docPath.startsWith('docs/')) { + docPath = docPath.substring('docs/'.length); + filePath = `${i18n != null ? `i18n/${i18n}docusaurus-plugin-content-docs/current/` : 'docs/'}${docPath}.md`; + } else if (docPath.startsWith('blog/')) { + filePath = `${i18n != null ? `i18n/${i18n}docusaurus-plugin-content-` : ''}${docPath}/index.mdx`; + } + return { filePath, repoName, branch, platform }; + }, + tests: [ + [ + // docs + 'https://open-digger.cn/docs/user_docs/label_data', + 'docs/user_docs/label_data.md', + ], + [ + // docs in sub directory + 'https://open-digger.cn/docs/user_docs/metrics/change_requests', + 'docs/user_docs/metrics/change_requests.md', + ], + [ + // blog + 'https://open-digger.cn/blog/2024-08-26-ospp-2023-analysis', + 'blog/2024-08-26-ospp-2023-analysis/index.mdx', + ], + [ + // english docs + 'https://open-digger.cn/en/docs/user_docs/label_data', + 'i18n/en/docusaurus-plugin-content-docs/current/user_docs/label_data.md', + ], + [ + // english blog + 'https://open-digger.cn/en/blog/2024-04-04-redis-analysis', + 'i18n/en/docusaurus-plugin-content-blog/2024-04-04-redis-analysis/index.mdx', + ], + ], + }, + { + domains: ['x-lab.info/oss101-bok'], + ruleFunction: (url) => { + const baseUrl = 'https://www.x-lab.info/oss101-bok/textbook/'; + const repoName = 'X-lab2017/oss101-bok'; + const branch = 'master'; + const platform = 'Github'; + if (!url.startsWith(baseUrl)) return null; + const docPath = url.replace(baseUrl, '').split('#')[0]; + const filePath = `docs/textbook/${docPath.slice(0, -1)}.md`; + return { filePath, repoName, branch, platform }; + }, + }, + { + domains: ['digital-textbooks/textbooks'], + ruleFunction: (url) => { + const baseUrl = 'https://www.x-lab.info/digital-textbooks/textbooks/'; + const repoName = 'wangyantong2000/docwebsite'; + const branch = 'main'; + const platform = 'Gitee'; + if (!url.startsWith(baseUrl)) return null; + const docPath = url.replace(baseUrl, '').split('#')[0]; + const filePath = `docs/textbooks/${docPath}index.md`; + return { filePath, repoName, branch, platform }; + }, + }, + { + domains: ['https://kaiyuanshe.github.io/oss-book'], + ruleFunction: (url) => { + const baseUrl = 'https://kaiyuanshe.github.io/oss-book/'; + const repoName = 'kaiyuanshe/oss-book'; + const branch = 'main'; + const platform = 'Github'; + if (!url.startsWith(baseUrl)) return null; + let docPath = url.replace(baseUrl, '').split('#')[0]; + if (docPath.startsWith('slide')) return null; + docPath = docPath.replace('.html', ''); + const filePath = `src/${docPath}.md`; + return { filePath, repoName, branch, platform }; + }, + tests: [ + ['https://kaiyuanshe.github.io/oss-book/Enterprise-and-Open-Source.html', 'src/Enterprise-and-Open-Source.md'], + ['https://kaiyuanshe.github.io/oss-book/slide/Enterprise-and-Open-Source.html', undefined], + [ + 'https://kaiyuanshe.github.io/oss-book/Software-Lifecycle-Management.html', + 'src/Software-Lifecycle-Management.md', + ], + ], + }, + { + domains: ['https://www.kaiwudb.com/'], + expired: () => new Date().getTime() > new Date('2025-01-01 00:00:00').getTime(), + ruleFunction: (url) => { + const baseUrl = 'https://www.kaiwudb.com/kaiwudb_docs/#/'; + const repoName = 'kwdb/docs'; + let branch = 'master'; + const platform = 'Gitee'; + if (!url.startsWith(baseUrl)) return null; + let docPath = url.replace(baseUrl, '').split('#')[0].replace('.html', ''); + function extractVersion(str) { + const pattern = /^v(\d+(\.\d+)*)\/.*$/; + const match = str.match(pattern); + if (match && match[1]) { + return match[1]; + } + return null; + } + const version = extractVersion(docPath); + if (version !== null) { + branch = version; + docPath = docPath.slice(version.length + 2); + } + const filePath = `${docPath}.md`; + return { filePath, repoName, branch, platform }; + }, + tests: [ + [ + 'https://www.kaiwudb.com/kaiwudb_docs/#/v2.0/sql-reference/data-type/data-type-ts-db.html', + 'sql-reference/data-type/data-type-ts-db.md', + ], + [ + 'https://www.kaiwudb.com/kaiwudb_docs/#/v2.0.4.1/deployment/bare-metal/bare-metal-deployment.html', + 'deployment/bare-metal/bare-metal-deployment.md', + ], + [ + 'https://www.kaiwudb.com/kaiwudb_docs/#/db-operation/error-code/error-code-postgresql.html', + 'db-operation/error-code/error-code-postgresql.md', + ], + ], + }, +]; + +function matchFastPrUrl(url) { + for (const rule of urlRules) { + const isMatch = rule.domains.some((domain) => url.includes(domain)); + if (!isMatch) continue; + if (rule.expired && rule.expired()) return null; + return rule.ruleFunction(url); + } + return null; +} + +// Make the function globally available if needed +if (typeof window !== 'undefined' && typeof window.document !== 'undefined') { + window.matchFastPrUrl = matchFastPrUrl; +} diff --git a/scripts/test_configs.js b/scripts/test_configs.js new file mode 100644 index 00000000..af534799 --- /dev/null +++ b/scripts/test_configs.js @@ -0,0 +1,21 @@ +import { urlRules } from '../public_configs/fast-pr-url-rules.js'; + +(async () => { + let hasError = false; + for (const rule of urlRules) { + const tests = rule.tests; + if (!tests) continue; + for (const test of tests) { + const url = test[0]; + const expected = test[1]; + const result = rule.ruleFunction(url); + if (result?.filePath !== expected) { + console.error(`Test failed for ${url}. Expected ${expected}, got ${result?.filePath}`); + hasError = true; + } + } + } + if (hasError) { + process.exit(-1); + } +})();