{"id":800,"date":"2026-04-14T15:50:40","date_gmt":"2026-04-14T07:50:40","guid":{"rendered":"https:\/\/blog.itsmygo.uk\/2026\/04\/14\/godot-4-6-web-%e9%81%8a%e6%88%b2%e8%87%aa%e5%8b%95%e9%83%a8%e7%bd%b2%e5%88%b0-cloudflare-pages%ef%bc%9agithub-actions-%e8%b8%a9%e5%9d%91%e5%85%a8%e7%b4%80%e9%8c%84\/"},"modified":"2026-04-14T15:50:40","modified_gmt":"2026-04-14T07:50:40","slug":"godot-4-6-web-%e9%81%8a%e6%88%b2%e8%87%aa%e5%8b%95%e9%83%a8%e7%bd%b2%e5%88%b0-cloudflare-pages%ef%bc%9agithub-actions-%e8%b8%a9%e5%9d%91%e5%85%a8%e7%b4%80%e9%8c%84","status":"publish","type":"post","link":"https:\/\/blog.itsmygo.uk\/wordpress\/2026\/04\/14\/godot-4-6-web-%e9%81%8a%e6%88%b2%e8%87%aa%e5%8b%95%e9%83%a8%e7%bd%b2%e5%88%b0-cloudflare-pages%ef%bc%9agithub-actions-%e8%b8%a9%e5%9d%91%e5%85%a8%e7%b4%80%e9%8c%84\/","title":{"rendered":"Godot 4.6 Web \u904a\u6232\u81ea\u52d5\u90e8\u7f72\u5230 Cloudflare Pages\uff1aGitHub Actions \u8e29\u5751\u5168\u7d00\u9304"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">Godot 4.6 Web \u904a\u6232\u81ea\u52d5\u90e8\u7f72\u5230 Cloudflare Pages\uff1aGitHub Actions \u8e29\u5751\u5168\u7d00\u9304<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">\u80cc\u666f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">CyberDesk \u662f\u4e00\u6b3e\u7528 Godot 4.6.2 \u958b\u767c\u7684 Web \u904a\u6232\uff08\u8cc7\u5b89\u57f9\u8a13\u4e92\u52d5\u5287\u672c\uff09\uff0c\u90e8\u7f72\u5728 Cloudflare Pages\uff0c\u7db2\u5740 <code>game.itsmygo.uk<\/code>\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u6211\u5e0c\u671b\u9054\u5230\u7684\u81ea\u52d5\u5316\u6d41\u7a0b\u662f\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\">1. \u5728 <span class=\"hljs-selector-tag\">Linear<\/span> <span class=\"hljs-selector-tag\">issue<\/span> \u7559\u8a00 <span class=\"hljs-keyword\">@claude<\/span> \u63cf\u8ff0\u8981\u6539\u4ec0\u9ebc\n<span class=\"hljs-number\">2<\/span>. Claude Code\uff08GitHub Action\uff09\u81ea\u52d5\u958b PR\n<span class=\"hljs-number\">3<\/span>. PR \u4e00\u958b\uff0c\u81ea\u52d5\u8dd1 Godot Web Export \u2192 push \u5230 PR \u5206\u652f\n<span class=\"hljs-number\">4<\/span>. Cloudflare Pages \u81ea\u52d5\u5efa preview URL \u2192 \u6211\u53ef\u4ee5\u5be6\u969b\u8a66\u73a9\n<span class=\"hljs-number\">5<\/span>. OK \u5c31 merge \u2192 \u89f8\u767c production \u90e8\u7f72\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u6574\u500b\u6d41\u7a0b\u88e1\u6700\u6838\u5fc3\u7684\u95dc\u9375\u5c31\u662f\uff1a<strong>\u8b93 GitHub Actions \u5728 Linux container \u5167\u8dd1 Godot headless export<\/strong>\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u807d\u8d77\u4f86\u5f88\u7c21\u55ae\u5c0d\u5427\uff1f\u9019\u7bc7\u5c31\u662f\u4f86\u544a\u8a34\u4f60\uff1a<strong>\u4e0d\u7c21\u55ae<\/strong>\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u70ba\u4ec0\u9ebc\u9700\u8981 CI \u4f86\u8dd1 Godot export<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u539f\u672c\u7684\u90e8\u7f72\u65b9\u5f0f\u662f\u672c\u6a5f\u8dd1\u4e00\u652f <code>deploy.sh<\/code>\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\"># deploy.sh\uff08\u672c\u6a5f\u7248\uff09<\/span>\nGODOT=<span class=\"hljs-string\">\"C:\/Users\/User\/work\/Godot_v4.6.2-stable_win64.exe\/...\"<\/span>\n$GODOT --headless --export-release <span class=\"hljs-string\">\"Web\"<\/span> build\/web\/index.html\ngzip -f build\/web\/index.wasm\ngit add build\/web\/\ngit commit -m <span class=\"hljs-string\">\"...\"<\/span>\ngit push origin master\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u554f\u984c\u662f\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>\u8def\u5f91\u5beb\u6b7b Windows<\/strong>\uff1aCI \u8dd1\u4e0d\u4e86<\/li>\n\n\n<li><strong>\u8981\u8a18\u5f97\u624b\u52d5\u8dd1<\/strong>\uff1amerge \u5b8c\u4e4b\u5f8c\u5e38\u5e38\u5fd8\u8a18\uff0c\u5c0e\u81f4\u7dda\u4e0a\u7248\u672c\u8ddf master \u4e0d\u540c\u6b65<\/li>\n\n\n<li><strong>Claude Code \u958b PR \u6642\u4e0d\u6703\u5e6b\u4f60\u8dd1 Godot<\/strong>\uff1a\u5b83\u53ea\u6539 <code>.gd<\/code> \u6a94\uff0c\u4e0d\u6703 export<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u6240\u4ee5\u52e2\u5fc5\u8981\u628a\u9019\u5957\u642c\u5230 GitHub Actions \u4e0a\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u6700\u7d42\u7684\u6210\u529f\u65b9\u6848\uff08\u5148\u7d66\u9b5a\uff09<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u61f6\u5f97\u770b\u8e29\u5751\u904e\u7a0b\u7684\u53ef\u4ee5\u76f4\u63a5\u7528\u9019\u4efd\u3002\u5b8c\u6574\u6a94\u6848\uff1a<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>.github\/workflows\/deploy.yml<\/code><\/h3>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">name: Deploy Web Build\n\non:\n  push:\n    branches: &#91;master]\n    paths:\n      - <span class=\"hljs-string\">'scripts\/**'<\/span>\n      - <span class=\"hljs-string\">'desktop.gd'<\/span>\n      - <span class=\"hljs-string\">'desktop.tscn'<\/span>\n      - <span class=\"hljs-string\">'project.godot'<\/span>\n      - <span class=\"hljs-string\">'export_presets.cfg'<\/span>\n      - <span class=\"hljs-string\">'fonts\/**'<\/span>\n      - <span class=\"hljs-string\">'icon.svg'<\/span>\n      - <span class=\"hljs-string\">'deploy-ci.sh'<\/span>\n      - <span class=\"hljs-string\">'.github\/workflows\/deploy.yml'<\/span>\n  pull_request:\n    branches: &#91;master]\n    types: &#91;opened, synchronize, reopened]\n    paths:\n      - <span class=\"hljs-string\">'scripts\/**'<\/span>\n      - <span class=\"hljs-string\">'desktop.gd'<\/span>\n      - <span class=\"hljs-string\">'desktop.tscn'<\/span>\n      - <span class=\"hljs-string\">'project.godot'<\/span>\n      - <span class=\"hljs-string\">'export_presets.cfg'<\/span>\n      - <span class=\"hljs-string\">'fonts\/**'<\/span>\n      - <span class=\"hljs-string\">'icon.svg'<\/span>\n      - <span class=\"hljs-string\">'deploy-ci.sh'<\/span>\n      - <span class=\"hljs-string\">'.github\/workflows\/deploy.yml'<\/span>\n  workflow_dispatch:\n\nconcurrency:\n  group: deploy-${{ github.head_ref || github.ref_name }}\n  cancel-in-progress: <span class=\"hljs-keyword\">true<\/span>\n\npermissions:\n  contents: read\n\njobs:\n  build-<span class=\"hljs-keyword\">and<\/span>-deploy:\n    runs-on: ubuntu-latest\n    timeout-minutes: <span class=\"hljs-number\">15<\/span>\n    container:\n      image: barichello\/godot-ci:<span class=\"hljs-number\">4.6<\/span><span class=\"hljs-number\">.2<\/span>\n\n    steps:\n      - name: Checkout repository\n        uses: actions\/checkout@v4\n        with:\n          token: ${{ secrets.DEPLOY_PAT }}\n          fetch-depth: <span class=\"hljs-number\">0<\/span>\n          ref: ${{ github.head_ref || github.ref }}\n\n      - name: Mark workspace safe <span class=\"hljs-keyword\">for<\/span> git\n        run: git config --<span class=\"hljs-keyword\">global<\/span> --add safe.directory <span class=\"hljs-string\">\"$GITHUB_WORKSPACE\"<\/span>\n\n      - name: Install runtime dependencies\n        run: |\n          apt-get update -qq\n          apt-get install -y -qq --no-install-recommends python3 libfontconfig1\n\n      - name: Verify Godot version\n        run: godot --version\n\n      - name: Install Godot <span class=\"hljs-number\">4.6<\/span><span class=\"hljs-number\">.2<\/span> export templates\n        run: |\n          TEMPLATE_DIR=<span class=\"hljs-string\">\"\/github\/home\/.local\/share\/godot\/export_templates\/4.6.2.stable\"<\/span>\n          <span class=\"hljs-keyword\">if<\/span> &#91; -f <span class=\"hljs-string\">\"${TEMPLATE_DIR}\/web_release.zip\"<\/span> ]; then\n            <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Templates \u5df2\u5b58\u5728\uff0c\u8df3\u904e\u4e0b\u8f09\"<\/span>\n            <span class=\"hljs-keyword\">exit<\/span> <span class=\"hljs-number\">0<\/span>\n          fi\n          mkdir -p <span class=\"hljs-string\">\"${TEMPLATE_DIR}\"<\/span>\n          cd \/tmp\n          wget -q <span class=\"hljs-string\">\"https:\/\/github.com\/godotengine\/godot\/releases\/download\/4.6.2-stable\/Godot_v4.6.2-stable_export_templates.tpz\"<\/span> \\\n            || wget -q <span class=\"hljs-string\">\"https:\/\/github.com\/godotengine\/godot-builds\/releases\/download\/4.6.2-stable\/Godot_v4.6.2-stable_export_templates.tpz\"<\/span>\n          unzip -q Godot_v4<span class=\"hljs-number\">.6<\/span><span class=\"hljs-number\">.2<\/span>-stable_export_templates.tpz\n          mv templates<span class=\"hljs-comment\">\/* \"${TEMPLATE_DIR}\/\"\n\n      - name: Run deploy-ci.sh (import + export + gzip)\n        run: |\n          chmod +x deploy-ci.sh\n          bash deploy-ci.sh\n\n      - name: Commit and push build\/web\/\n        run: |\n          git config user.name \"github-actions&#91;bot]\"\n          git config user.email \"41898282+github-actions&#91;bot]<span class=\"hljs-doctag\">@users<\/span>.noreply.github.com\"\n          git add build\/web\/\n          if git diff --cached --quiet; then\n            echo \"build\/web\/ \u6c92\u6709\u8b8a\u52d5\uff0c\u8df3\u904e commit\"\n            exit 0\n          fi\n          TARGET_BRANCH=\"${{ github.head_ref || github.ref_name }}\"\n          SOURCE_MSG=$(git log -1 --pretty=%s HEAD)\n          if &#91; \"${{ github.event_name }}\" = \"pull_request\" ]; then\n            COMMIT_TYPE=\"preview\"\n          else\n            COMMIT_TYPE=\"deploy\"\n          fi\n          git commit -F - &lt;&lt;COMMIT_MSG\n          ci(${COMMIT_TYPE}): web build for ${TARGET_BRANCH} &#91;skip ci]\n\n          Source: ${SOURCE_MSG}\n          Commit: ${{ github.sha }}\n          COMMIT_MSG\n          git push origin \"HEAD:${TARGET_BRANCH}\" || (git pull --rebase origin \"${TARGET_BRANCH}\" &amp;&amp; git push origin \"HEAD:${TARGET_BRANCH}\")\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><code>deploy-ci.sh<\/code><\/h3>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">#!\/bin\/bash<\/span>\nset -e\ncd <span class=\"hljs-string\">\"$(dirname \"<\/span>$<span class=\"hljs-number\">0<\/span><span class=\"hljs-string\">\")\"<\/span>\nGODOT=<span class=\"hljs-string\">\"${GODOT:-godot}\"<\/span>\n\ncp build\/web\/index.html build\/web\/index.html.custom <span class=\"hljs-number\">2<\/span>&gt;\/dev\/<span class=\"hljs-keyword\">null<\/span> || <span class=\"hljs-keyword\">true<\/span>\n\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Godot import (\u7522\u751f .godot\/imported cache)...\"<\/span>\n$GODOT --headless --import <span class=\"hljs-number\">2<\/span>&gt;&amp;<span class=\"hljs-number\">1<\/span> || <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"\u8b66\u544a\uff1agodot --import \u56de\u50b3\u975e 0\uff0c\u7e7c\u7e8c\u5617\u8a66 export\"<\/span>\n\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Godot Web Export...\"<\/span>\n$GODOT --headless --export-release <span class=\"hljs-string\">\"Web\"<\/span> <span class=\"hljs-string\">\"build\/web\/index.html\"<\/span>\n\n<span class=\"hljs-keyword\">if<\/span> &#91; -f build\/web\/index.html.custom ]; then\n    NEW_CONFIG=$(grep -o <span class=\"hljs-string\">'const GODOT_CONFIG = {.*};'<\/span> build\/web\/index.html || <span class=\"hljs-keyword\">true<\/span>)\n    cp build\/web\/index.html.custom build\/web\/index.html\n    <span class=\"hljs-keyword\">if<\/span> &#91; -n <span class=\"hljs-string\">\"$NEW_CONFIG\"<\/span> ]; then\n        export NEW_CONFIG\n        python3 - &lt;&lt;<span class=\"hljs-string\">'PY'<\/span>\nimport os, re, sys\nnew_cfg = os.environ&#91;<span class=\"hljs-string\">'NEW_CONFIG'<\/span>]\nwith open(<span class=\"hljs-string\">'build\/web\/index.html'<\/span>, <span class=\"hljs-string\">'r'<\/span>, encoding=<span class=\"hljs-string\">'utf-8'<\/span>) <span class=\"hljs-keyword\">as<\/span> f:\n    html = f.read()\nnew_html, count = re.subn(r<span class=\"hljs-string\">'const GODOT_CONFIG = \\{.*?\\};'<\/span>, new_cfg, html)\n<span class=\"hljs-keyword\">if<\/span> count == <span class=\"hljs-number\">0<\/span>:\n    <span class=\"hljs-keyword\">print<\/span>(<span class=\"hljs-string\">'\u932f\u8aa4\uff1a\u5728 index.html \u627e\u4e0d\u5230 GODOT_CONFIG\uff0c\u7121\u6cd5\u66ff\u63db'<\/span>, file=sys.stderr)\n    sys.<span class=\"hljs-keyword\">exit<\/span>(<span class=\"hljs-number\">1<\/span>)\nwith open(<span class=\"hljs-string\">'build\/web\/index.html'<\/span>, <span class=\"hljs-string\">'w'<\/span>, encoding=<span class=\"hljs-string\">'utf-8'<\/span>) <span class=\"hljs-keyword\">as<\/span> f:\n    f.write(new_html)\n<span class=\"hljs-keyword\">print<\/span>(f<span class=\"hljs-string\">'\u5df2\u66f4\u65b0 GODOT_CONFIG\uff08\u66ff\u63db {count} \u8655\uff09'<\/span>)\nPY\n    fi\n    rm build\/web\/index.html.custom\nfi\n\n<span class=\"hljs-comment\"># \u58d3\u7e2e wasm\uff08CF Pages 25MB \u9650\u5236\uff09<\/span>\nMAGIC=$(od -An -tx1 -N2 build\/web\/index.wasm | tr -d <span class=\"hljs-string\">' \\n'<\/span>)\n<span class=\"hljs-keyword\">if<\/span> &#91; <span class=\"hljs-string\">\"$MAGIC\"<\/span> = <span class=\"hljs-string\">\"0061\"<\/span> ]; then\n    gzip -f build\/web\/index.wasm\n    mv build\/web\/index.wasm.gz build\/web\/index.wasm\nfi\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">OK\uff0c\u9019\u5c31\u662f\u6700\u5f8c\u53ef\u4ee5\u52d5\u7684\u7248\u672c\u3002\u4e0b\u9762\u662f\u600e\u9ebc\u4e00\u6b65\u6b65\u722c\u5230\u9019\u88e1\u7684\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u8e29\u5751\u8a18\u9304<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u5751 1\uff1a<code>barichello\/godot-ci:4.6.2<\/code> image \u7f3a export templates<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u7b2c\u4e00\u6b21\u8dd1 workflow\uff0c\u639b\u5728 export step\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">ERROR: Cannot <span class=\"hljs-keyword\">export<\/span> project <span class=\"hljs-keyword\">with<\/span> preset <span class=\"hljs-string\">\"Web\"<\/span> due to configuration errors:\nNo <span class=\"hljs-keyword\">export<\/span> template found at the expected path:\n<span class=\"hljs-regexp\">\/github\/<\/span>home\/.local\/share\/godot\/export_templates\/<span class=\"hljs-number\">4.6<\/span><span class=\"hljs-number\">.2<\/span>.stable\/web_debug.zip\nNo <span class=\"hljs-keyword\">export<\/span> template found at the expected path:\n<span class=\"hljs-regexp\">\/github\/<\/span>home\/.local\/share\/godot\/export_templates\/<span class=\"hljs-number\">4.6<\/span><span class=\"hljs-number\">.2<\/span>.stable\/web_release.zip\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><code>barichello\/godot-ci<\/code> \u9019\u500b image \u865f\u7a31\u5df2\u7d93\u5167\u5efa Godot \u8ddf export templates\uff0c\u4f46\u5be6\u969b\u4e0a 4.6.2 \u9019\u500b tag \u5167 templates \u6c92\u6709\u88ab\u653e\u5728 Godot \u9810\u671f\u7684\u8def\u5f91\uff08<code>$HOME\/.local\/share\/godot\/export_templates\/&lt;version&gt;.stable\/<\/code>\uff09\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u53ef\u80fd\u7684\u539f\u56e0\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>image build \u6642\u662f root\uff0cHOME \u662f <code>\/root\/.local\/...<\/code>\uff0c\u4f46 GitHub Actions runtime HOME \u662f <code>\/github\/home\/.local\/...<\/code><\/li>\n\n\n<li>\u6216\u662f image \u5167\u7248\u672c\u5b57\u4e32\u4e0d\u4e00\u81f4\uff08<code>4.6.2-stable<\/code> vs <code>4.6.2.stable<\/code>\uff09<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u6700\u53ef\u9760\u7684\u89e3\u6cd5\uff1a<strong>workflow \u81ea\u5df1\u4e0b\u8f09 templates<\/strong>\uff0c\u4e0d\u4f9d\u8cf4 image\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">- name: Install Godot <span class=\"hljs-number\">4.6<\/span><span class=\"hljs-number\">.2<\/span> <span class=\"hljs-keyword\">export<\/span> templates\n  <span class=\"hljs-attr\">run<\/span>: |\n    TEMPLATE_DIR=<span class=\"hljs-string\">\"\/github\/home\/.local\/share\/godot\/export_templates\/4.6.2.stable\"<\/span>\n    mkdir -p <span class=\"hljs-string\">\"${TEMPLATE_DIR}\"<\/span>\n    cd \/tmp\n    wget -q <span class=\"hljs-string\">\"https:\/\/github.com\/godotengine\/godot\/releases\/download\/4.6.2-stable\/Godot_v4.6.2-stable_export_templates.tpz\"<\/span>\n    unzip -q Godot_v4<span class=\"hljs-number\">.6<\/span><span class=\"hljs-number\">.2<\/span>-stable_export_templates.tpz\n    mv templates<span class=\"hljs-comment\">\/* \"${TEMPLATE_DIR}\/\"\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u6ce8\u610f\uff1a\u7528 <code>\/github\/home<\/code> \u9019\u500b\u7d55\u5c0d\u8def\u5f91\uff0c\u4e0d\u8981\u7528 <code>$HOME<\/code>\uff0c\u56e0\u70ba container \u5167 root user \u7684 HOME \u662f <code>\/root<\/code> \u4f46 GitHub Actions step \u8dd1\u8d77\u4f86\u6642 HOME \u8b8a\u6210 <code>\/github\/home<\/code>\uff0c\u6703\u932f\u4f4d\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u5751 2\uff1apython3 \u4e0d\u5b58\u5728 + <code>2&gt;\/dev\/null<\/code> \u628a\u932f\u8aa4\u541e\u6389\u4e86<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4fee\u597d templates \u5f8c\uff0cexport \u7d42\u65bc\u8dd1\u904e\u4e86\uff0c\u4f46\u51fa\u73fe\u4e00\u689d\u8b66\u544a\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\"><span><code class=\"hljs\">\u8b66\u544a\uff1a\u7121\u6cd5\u66f4\u65b0 GODOT_CONFIG\uff0c\u4f7f\u7528\u820a\u503c\n<\/code><\/span><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">deploy-ci.sh \u88e1\u7684\u9019\u6bb5 python\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">python3 -c <span class=\"hljs-string\">\"\nimport re\nhtml = open('build\/web\/index.html','r',encoding='utf-8').read()\nnew_cfg = '''$NEW_CONFIG'''\n...\n\"<\/span> <span class=\"hljs-number\">2<\/span>&gt;\/dev\/<span class=\"hljs-keyword\">null<\/span> || <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"\u8b66\u544a\uff1a\u7121\u6cd5\u66f4\u65b0 GODOT_CONFIG\uff0c\u4f7f\u7528\u820a\u503c\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">\u70ba\u4ec0\u9ebc\u9019\u662f\u500b\u5927\u554f\u984c<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>GODOT_CONFIG<\/code> \u662f Godot Web build \u7528\u7684 JS \u8b8a\u6578\uff0c\u5167\u5bb9\u9577\u9019\u6a23\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> GODOT_CONFIG = {\n  <span class=\"hljs-string\">\"executable\"<\/span>: <span class=\"hljs-string\">\"index\"<\/span>,\n  <span class=\"hljs-string\">\"fileSizes\"<\/span>: {\n    <span class=\"hljs-string\">\"index.pck\"<\/span>: <span class=\"hljs-number\">18754960<\/span>,\n    <span class=\"hljs-string\">\"index.wasm\"<\/span>: <span class=\"hljs-number\">9435514<\/span>\n  },\n  ...\n};\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><code>fileSizes<\/code> \u5fc5\u9808\u8ddf\u5be6\u969b\u7684 <code>index.pck<\/code> \/ <code>index.wasm<\/code> \u5c0d\u5f97\u4e0a\uff0cGodot loader \u624d\u80fd\u6b63\u78ba\u986f\u793a\u8f09\u5165\u9032\u5ea6\u689d\u8ddf\u9a57\u8b49\u6a94\u6848\u5b8c\u6574\u6027\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u5982\u679c python \u5931\u6557\uff0c<code>index.html<\/code> \u4fdd\u7559<strong>\u820a\u7684<\/strong> GODOT_CONFIG\uff0c\u4f46 <code>index.pck<\/code> \u8ddf <code>index.wasm<\/code> \u662f<strong>\u65b0\u7684<\/strong>\u2014\u2014\u5927\u5c0f\u5c0d\u4e0d\u4e0a\uff0cruntime \u6703\u70b8\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\u70ba\u4ec0\u9ebc python3 \u5931\u6557<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u5169\u500b\u539f\u56e0\u758a\u52a0\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li><strong><code>barichello\/godot-ci<\/code> image \u6c92\u88dd python3<\/strong>\uff08\u6216\u88dd\u4e86\u4f46\u53eb <code>python<\/code> \u800c\u975e <code>python3<\/code>\uff09<\/li>\n\n\n<li><strong><code>2&gt;\/dev\/null<\/code> \u628a\u932f\u8aa4\u541e\u4e86<\/strong>\u2014\u2014\u5c0e\u81f4\u6839\u672c\u770b\u4e0d\u5230\u300cpython3: command not found\u300d\u9019\u884c\u8a0a\u606f\uff0c\u53ea\u770b\u5230\u4e00\u500b\u8f15\u98c4\u98c4\u7684\u300c\u4f7f\u7528\u820a\u503c\u300d\u8b66\u544a<\/li>\n\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">\u4fee\u6b63<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u5169\u4ef6\u4e8b\u4e00\u8d77\u505a\uff1a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>(1) \u78ba\u4fdd python3 \u5b58\u5728<\/strong>\u2014\u2014\u5728 deploy.yml \u52a0\u4e00\u500b install step\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">- name: Install runtime dependencies\n  <span class=\"hljs-attr\">run<\/span>: |\n    apt-<span class=\"hljs-keyword\">get<\/span> update -qq\n    apt-<span class=\"hljs-keyword\">get<\/span> install -y -qq --no-install-recommends python3 libfontconfig1\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><code>libfontconfig1<\/code> \u662f\u9806\u624b\u88dd\u7684\uff0c\u96d6\u7136 fontconfig \u8b66\u544a\u7121\u5bb3\uff08\u5c08\u6848\u7528\u81ea\u8a02\u5b57\u578b\uff09\uff0c\u4f46 log \u770b\u8d77\u4f86\u4e7e\u6de8\u591a\u4e86\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>(2) python \u5beb\u6cd5\u6539\u7528 env var + quoted heredoc + \u62ff\u6389 2>\/dev\/null<\/strong>\uff1a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u539f\u672c\u932f\u8aa4\u5beb\u6cd5\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">python3 -c <span class=\"hljs-string\">\"\nnew_cfg = '''$NEW_CONFIG'''  # \u2190 shell \u76f4\u63a5\u628a\u5b57\u4e32\u585e\u9032\u4f86\uff0c\u53ef\u80fd\u70b8\n\"<\/span> <span class=\"hljs-number\">2<\/span>&gt;\/dev\/<span class=\"hljs-keyword\">null<\/span>  <span class=\"hljs-comment\"># \u2190 \u932f\u8aa4\u88ab\u541e<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u6b63\u78ba\u5beb\u6cd5\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">export NEW_CONFIG\npython3 - &lt;&lt;<span class=\"hljs-string\">'PY'<\/span>   <span class=\"hljs-comment\"># \u2190 quoted delimiter\uff0cpython \u539f\u59cb\u78bc\u4e0d\u88ab shell \u89e3\u6790<\/span>\nimport os, re, sys\nnew_cfg = os.environ&#91;<span class=\"hljs-string\">'NEW_CONFIG'<\/span>]  <span class=\"hljs-comment\"># \u2190 \u5f9e env var \u62ff<\/span>\nnew_html, count = re.subn(r<span class=\"hljs-string\">'const GODOT_CONFIG = \\{.*?\\};'<\/span>, new_cfg, html)\n<span class=\"hljs-keyword\">if<\/span> count == <span class=\"hljs-number\">0<\/span>:\n    <span class=\"hljs-keyword\">print<\/span>(<span class=\"hljs-string\">'\u932f\u8aa4\uff1a\u627e\u4e0d\u5230 GODOT_CONFIG'<\/span>, file=sys.stderr)\n    sys.<span class=\"hljs-keyword\">exit<\/span>(<span class=\"hljs-number\">1<\/span>)  <span class=\"hljs-comment\"># \u2190 \u5931\u6557\u5c31 fail loud<\/span>\n<span class=\"hljs-keyword\">print<\/span>(f<span class=\"hljs-string\">'\u5df2\u66f4\u65b0 GODOT_CONFIG\uff08\u66ff\u63db {count} \u8655\uff09'<\/span>)\nPY\n<span class=\"hljs-comment\"># \u4e0d\u518d\u6709 2&gt;\/dev\/null<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u95dc\u9375\u6539\u8b8a\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><code>&lt;&lt;'PY'<\/code>\uff08\u55ae\u5f15\u865f quoted heredoc\uff09\u8b93 python source code \u4e0d\u6703\u88ab shell \u4e8c\u6b21\u89e3\u6790<\/li>\n\n\n<li>\u900f\u904e <code>export NEW_CONFIG<\/code> \u74b0\u5883\u8b8a\u6578\u50b3\u503c\uff0c\u907f\u514d shell \u5b57\u4e32\u5167\u63d2\u89e3\u6790\u7834\u58de GODOT_CONFIG \u5167\u5bb9<\/li>\n\n\n<li><code>re.subn<\/code> \u56de\u50b3\u66ff\u63db\u6b21\u6578\uff0ccount \u70ba 0 \u6642\u76f4\u63a5 fail<\/li>\n\n\n<li>\u62ff\u6389 <code>2&gt;\/dev\/null<\/code>\uff0c\u4e0b\u6b21\u51fa\u554f\u984c\u6642\u770b\u5f97\u5230\u771f\u6b63\u7684\u932f\u8aa4<\/li>\n\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u5751 3\uff1aCloudflare Pages \u908a\u7de3\u5feb\u53d6\u8b93\u6211\u4ee5\u70ba deploy \u6c92\u6210\u529f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4fee\u597d\u524d\u9762\u5169\u5751\u4e4b\u5f8c\uff0cPR merge \u2192 workflow \u8dd1 \u2192 commit build\/web\/ \u56de master\uff0c\u5168\u90e8\u6210\u529f\u3002\u4f46\u958b <code>game.itsmygo.uk<\/code> \u9084\u662f\u770b\u5230\u820a\u7248\u7b2c 9 \u95dc\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u7b2c\u4e00\u500b\u76f4\u89ba\uff1a\u300cdeploy-ci.sh \u662f\u4e0d\u662f\u6c92\u8dd1\uff1f\u300d<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u4f46\u5be6\u969b\u4e0a\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">git log --oneline <span class=\"hljs-number\">-5<\/span>\n<span class=\"hljs-comment\"># a494cf3 ci(deploy): web build for master &#91;skip ci]   \u2190 bot \u81ea\u52d5 commit<\/span>\n<span class=\"hljs-comment\"># abe14ef Merge pull request #8 ...\u7b2c9\u95dc...             \u2190 \u6211\u7684 merge<\/span>\n\ngit show --stat a494cf3\n<span class=\"hljs-comment\"># build\/web\/index.html |   2 +-<\/span>\n<span class=\"hljs-comment\"># build\/web\/index.pck  | Bin 18752080 -&gt; 18754960 bytes  \u2190 \u771f\u7684\u6709\u8b8a\u52d5\uff01<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u6240\u4ee5 deploy \u5b8c\u5168\u6b63\u5e38\uff0c\u554f\u984c\u51fa\u5728\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>CF Pages \u908a\u7de3\u7bc0\u9ede\u5feb\u53d6\u820a\u7248 <code>index.pck<\/code><\/strong><\/li>\n\n\n<li><strong>\u700f\u89bd\u5668\u81ea\u5df1\u4e5f\u5feb\u53d6 binary asset<\/strong><\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u9a57\u8b49\u65b9\u6cd5\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\"># \u76f4\u63a5\u6293\u7dda\u4e0a\u7684 pck \u6a94\u6848\u5927\u5c0f\uff0c\u8ddf git \u5c0d\u7167<\/span>\ncurl -sI https:<span class=\"hljs-comment\">\/\/game.itsmygo.uk\/index.pck | grep -i content-length<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u5982\u679c\u56de\u50b3 <code>18752080<\/code> \u2192 \u662f\u820a\u7248\uff08\u5feb\u53d6\u6c92\u6e05\uff09 \u5982\u679c\u56de\u50b3 <code>18754960<\/code> \u2192 \u662f\u65b0\u7248<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u89e3\u6cd5\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>\u7121\u75d5\u8996\u7a97<\/strong>\u6e2c\u8a66<\/li>\n\n\n<li>\u6216 hard refresh\uff08<code>Ctrl + Shift + R<\/code>\uff09<\/li>\n\n\n<li>\u6216\u8a2d\u5b9a CF Pages cache rules\uff0c\u8b93 <code>.pck<\/code> \/ <code>.wasm<\/code> \u4e0d\u8981 cache \u592a\u4e45<\/li>\n\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u91cd\u9ede\uff1a\u4e0b\u6b21\u600e\u9ebc\u8ddf AI \u8b1b\u624d\u80fd\u5feb\u901f\u89e3\u6c7a<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u6b21\u8e29\u5751\u7684\u904e\u7a0b\uff0c\u524d\u671f\u6211\u554f AI \u7684\u65b9\u5f0f\u5f88\u6a21\u7cca\uff1a\u300c\u7db2\u7ad9\u6c92\u66f4\u65b0\uff0c\u600e\u9ebc\u8fa6\uff1f\u300d\u9019\u7a2e\u554f\u6cd5 AI \u53ea\u80fd\u731c\u3002\u5f8c\u4f86\u6211\u5b78\u6703\u628a\u8cc7\u8a0a\u8b1b\u6e05\u695a\uff0c\u6bcf\u6b21\u554f\u984c\u90fd\u80fd\u5728 1-2 \u8f2a\u5167\u89e3\u6c7a\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u274c \u4e0d\u8981\u9019\u6a23\u554f<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u6211\u7684 deploy \u6c92\u8dd1 \/ \u7db2\u7ad9\u6c92\u66f4\u65b0 \/ \u600e\u9ebc\u8fa6<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">AI \u6703\u7d66\u4f60 5 \u500b\u53ef\u80fd\u7684\u65b9\u5411\uff0c\u4f60\u9084\u662f\u8981\u81ea\u5df1\u4e00\u500b\u4e00\u500b\u8a66\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u2705 \u61c9\u8a72\u9019\u6a23\u554f<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">1. \u628a\u5be6\u969b\u770b\u5230\u7684 vs \u9810\u671f\u7684\u8b1b\u6e05\u695a<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u6211\u9810\u671f PR merge \u5f8c <code>game.itsmygo.uk<\/code> \u6703\u770b\u5230\u7b2c 9 \u95dc\u7684\u65b0\u4ecb\u9762\uff08AI \u52a9\u624b\u5c0d\u8a71\u6846\uff09<br>\u4f46\u5be6\u969b\u6253\u958b\u9084\u662f\u820a\u7684\uff08\u8a18\u4e8b\u672c\u4ecb\u9762\uff09<br>\u6211\u5df2\u7d93 hard refresh \u904e\u4e86<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u6a23 AI \u99ac\u4e0a\u77e5\u9053\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>\u9810\u671f\uff1a\u7b2c 9 \u95dc\u4ecb\u9762\u8b8a\u5316<\/li>\n\n\n<li>\u5be6\u969b\uff1a\u6c92\u8b8a\u5316<\/li>\n\n\n<li>\u6392\u9664\uff1a\u700f\u89bd\u5668\u5feb\u53d6\u5df2\u8a66\u904e<\/li>\n\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">2. \u628a\u932f\u8aa4\u8a0a\u606f**\u5b8c\u6574**\u8cbc\u4e0a\u4f86<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u274c \u4e0d\u8981\u8aaa\uff1a\u300cexport \u5931\u6557\u4e86\u300d \u2705 \u8981\u8cbc\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">ERROR: Cannot <span class=\"hljs-keyword\">export<\/span> project <span class=\"hljs-keyword\">with<\/span> preset <span class=\"hljs-string\">\"Web\"<\/span> due to configuration errors:\nNo <span class=\"hljs-keyword\">export<\/span> template found at the expected path:\n<span class=\"hljs-regexp\">\/github\/<\/span>home\/.local\/share\/godot\/export_templates\/<span class=\"hljs-number\">4.6<\/span><span class=\"hljs-number\">.2<\/span>.stable\/web_debug.zip\n   <span class=\"hljs-attr\">at<\/span>: _fs_changed (editor\/editor_node.cpp:<span class=\"hljs-number\">1332<\/span>)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u5f9e\u932f\u8aa4\u8a0a\u606f\u88e1 AI \u53ef\u4ee5\u770b\u5230\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>\u8def\u5f91<\/strong> <code>\/github\/home\/.local\/share\/godot\/...<\/code> \u2192 \u77e5\u9053 HOME \u662f\u54ea<\/li>\n\n\n<li><strong>\u6a94\u540d<\/strong> <code>web_debug.zip<\/code> \u2192 \u77e5\u9053\u662f export templates \u554f\u984c<\/li>\n\n\n<li><strong>\u7248\u672c<\/strong> <code>4.6.2.stable<\/code> \u2192 \u77e5\u9053\u7248\u672c\u5b57\u4e32\u683c\u5f0f<\/li>\n\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">3. \u628a\u300c\u9a57\u8b49\u8b49\u64da\u300d\u4e00\u8d77\u7d66<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u554f\u984c\uff1a\u300c\u70ba\u4ec0\u9ebc\u6c92\u66f4\u65b0\uff1f\u300d\u61c9\u8a72\u88dc\u4e0a\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\"># git \u7aef\u7684\u8b49\u64da<\/span>\n$ git log --oneline <span class=\"hljs-number\">-5<\/span>\na494cf3 ci(deploy): web build <span class=\"hljs-keyword\">for<\/span> master &#91;skip ci]\nabe14ef Merge pull request <span class=\"hljs-comment\">#8 from skcht\/claude\/issue-6<\/span>\n\n$ git show --stat a494cf3\n build\/web\/index.pck | Bin <span class=\"hljs-number\">18752080<\/span> -&gt; <span class=\"hljs-number\">18754960<\/span> bytes\n\n<span class=\"hljs-comment\"># \u7dda\u4e0a\u7684\u8b49\u64da<\/span>\n$ curl -sI https:<span class=\"hljs-comment\">\/\/game.itsmygo.uk\/index.pck | grep content-length<\/span>\ncontent-length: <span class=\"hljs-number\">18752080<\/span>   \u2190 \u820a\u7684\uff01\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u5169\u908a\u4e00\u6bd4\u5c0d\uff0cAI \u99ac\u4e0a\u770b\u51fa\uff1a\u300cgit \u662f 18754960\uff0c\u7dda\u4e0a\u662f 18752080\uff0c\u6240\u4ee5 CF \u9084\u6c92\u90e8\u7f72\u6216\u6709\u5feb\u53d6\u300d\u2014\u2014\u4e0d\u7528\u731c\u4e86\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">4. \u4e0d\u8981\u7528 <code>2&gt;\/dev\/null<\/code> \u6216 <code>|| true<\/code> \u628a\u932f\u8aa4\u541e\u6389<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u500b\u662f\u9019\u6b21\u6700\u5927\u7684\u6559\u8a13\u3002\u539f\u672c\u6211\u6709\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">python3 -c <span class=\"hljs-string\">\"...\"<\/span> <span class=\"hljs-number\">2<\/span>&gt;<span class=\"hljs-regexp\">\/dev\/<\/span><span class=\"hljs-literal\">null<\/span> || echo <span class=\"hljs-string\">\"\u8b66\u544a\uff1a\u4f7f\u7528\u820a\u503c\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u7d50\u679c\u554f\u984c\u51fa\u73fe\u6642\uff0clog \u53ea\u770b\u5230\u300c\u8b66\u544a\uff1a\u4f7f\u7528\u820a\u503c\u300d\uff0c<strong>\u6839\u672c\u4e0d\u77e5\u9053 python3 \u70ba\u4ec0\u9ebc\u5931\u6557<\/strong>\u3002\u5f8c\u4f86\u624d\u767c\u73fe\u662f <code>python3<\/code> \u5728 container \u5167\u6839\u672c\u6c92\u88dd\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u6b63\u78ba\u59ff\u52e2\uff1a<strong>\u932f\u8aa4\u5c31\u8b93\u5b83 fail loud<\/strong>\u3002\u5982\u679c\u771f\u7684\u8981 fallback\uff0c\u81f3\u5c11\u8981\u628a stderr \u6293\u51fa\u4f86\u5370\u7d66\u4eba\u770b\u3002<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\"># \u932f\u8aa4\u793a\u7bc4<\/span>\ncommand <span class=\"hljs-number\">2<\/span>&gt;\/dev\/<span class=\"hljs-keyword\">null<\/span> || fallback\n\n<span class=\"hljs-comment\"># \u6b63\u78ba\u793a\u7bc4<\/span>\n<span class=\"hljs-keyword\">if<\/span> ! output=$(command <span class=\"hljs-number\">2<\/span>&gt;&amp;<span class=\"hljs-number\">1<\/span>); then\n    <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"command \u5931\u6557\uff1a$output\"<\/span> &gt;&amp;<span class=\"hljs-number\">2<\/span>\n    fallback\nfi\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">5. \u628a\u74b0\u5883\u4e0a\u4e0b\u6587\u4e00\u8d77\u8b1b<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u7576\u4f60\u554f CI \u554f\u984c\uff0c\u8981\u9644\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>\u4ec0\u9ebc image \/ OS<\/strong> \u2014 <code>barichello\/godot-ci:4.6.2<\/code> (Ubuntu 22.04)<\/li>\n\n\n<li><strong>\u8dd1\u4ec0\u9ebc\u6307\u4ee4<\/strong> \u2014 <code>godot --headless --export-release \"Web\"<\/code><\/li>\n\n\n<li><strong>\u672c\u6a5f\u8dd1\u5f97\u8d77\u4f86\u55ce\uff1f<\/strong> \u2014 \u5c0d\uff0c\u672c\u6a5f Windows + Godot 4.6.2 OK<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">AI \u770b\u5230\u300c\u672c\u6a5f OK\uff0cCI \u4e0d OK\u300d\u5c31\u6703\u512a\u5148\u5f80\u300c\u74b0\u5883\u5dee\u7570\u300d\u65b9\u5411\u627e\u554f\u984c\uff08\u7f3a\u5957\u4ef6\u3001\u8def\u5f91\u5dee\u7570\u3001\u6b0a\u9650\uff09\uff0c\u800c\u4e0d\u662f\u53bb\u61f7\u7591\u4f60\u7684 GDScript\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">6. \u4e00\u6b21\u53ea\u554f\u4e00\u500b\u554f\u984c<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u274c \u300c\u6211\u7684 deploy \u8dd1\u4e86\u4f46\u7db2\u7ad9\u6c92\u66f4\u65b0\u800c\u4e14 fontconfig \u4e5f\u5831\u932f\u300d<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u6a23 AI \u6703\u5206\u6563\u6ce8\u610f\u529b\uff0c\u53ef\u80fd\u53bb\u8655\u7406 fontconfig\uff08\u7121\u5bb3\u8b66\u544a\uff09\u800c\u5ffd\u7565\u771f\u6b63\u7684\u554f\u984c\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2705 \u300c\u7db2\u7ad9\u6c92\u66f4\u65b0\u7b2c 9 \u95dc\u5167\u5bb9\u3002\u6211\u770b\u5230 a494cf3 commit \u78ba\u5be6\u6709\u6539 index.pck\uff0c\u4f46\u7dda\u4e0a\u6293\u5230\u7684\u9084\u662f\u820a\u7248 size\u3002\u300d<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u805a\u7126\u6838\u5fc3\u554f\u984c\uff0c\u7121\u95dc\u7684\u6b21\u8981 issue \u4e4b\u5f8c\u518d\u554f\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u7d50\u8ad6<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u6574\u500b\u8e29\u5751\u904e\u7a0b\u7684\u6642\u9593\u8ef8\u5927\u6982\u662f\uff1a<\/p>\n\n\n<div class=\"cbc-code-wrapper\"><div class=\"cbc-code-bar\"><button class=\"cbc-copy-button\">Copy<\/button><\/div><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">\u5beb deploy.yml + deploy-ci.sh   \u2192  \u534a\u5c0f\u6642\n\u8e29\u5751 <span class=\"hljs-number\">1<\/span>\uff08templates\uff09            \u2192  <span class=\"hljs-number\">10<\/span> \u5206\u9418\u89e3\u6c7a\n\u8e29\u5751 <span class=\"hljs-number\">2<\/span>\uff08python3 + \u541e\u932f\u8aa4\uff09     \u2192  <span class=\"hljs-number\">1<\/span> \u5c0f\u6642\uff08\u56e0\u70ba <span class=\"hljs-number\">2<\/span>&gt;<span class=\"hljs-regexp\">\/dev\/<\/span><span class=\"hljs-literal\">null<\/span> \u4e00\u76f4\u8aa4\u5c0e\uff09\n\u8e29\u5751 <span class=\"hljs-number\">3<\/span>\uff08CF \u5feb\u53d6\u4ee5\u70ba\u6c92 deploy\uff09 \u2192  <span class=\"hljs-number\">20<\/span> \u5206\u9418\uff08\u5dee\u9ede\u6253\u6389\u91cd\u505a\uff09\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u6700\u5927\u7684\u6642\u9593\u6d6a\u8cbb\u5c31\u5728\u8e29\u5751 2\uff0c\u6839\u672c\u539f\u56e0\u662f<strong>\u81ea\u5df1\u628a\u932f\u8aa4\u8a0a\u606f\u84cb\u6389\u4e86<\/strong>\u3002\u5982\u679c\u4e00\u958b\u59cb deploy-ci.sh \u4e0d\u8981\u5beb <code>2&gt;\/dev\/null<\/code>\uff0c\u7b2c\u4e00\u6b21\u8dd1\u5c31\u80fd\u76f4\u63a5\u770b\u5230\u300cpython3: command not found\u300d\uff0c10 \u79d2\u9418\u89e3\u6c7a\u3002<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">**\u4e00\u689d\u6559\u8a13**\uff1a\u5beb CI script \u5be7\u53ef\u5435\u4e5f\u4e0d\u8981\u5b89\u975c\u3002\u932f\u8aa4\u8a0a\u606f\u7684\u6210\u672c\u6c38\u9060\u9060\u4f4e\u65bc debug \u6642\u9593\u7684\u6210\u672c\u3002<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u9644\uff1a\u5b8c\u6574\u7684\u89f8\u767c\u6d41\u7a0b<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u6210\u529f\u90e8\u7f72\u5f8c\uff0c\u73fe\u5728\u7684\u6d41\u7a0b\u662f\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li>\u5728 Linear issue \u7559\u8a00 <code>@claude \u628a\u7b2c X \u95dc\u7684 Y \u6539\u6210 Z<\/code><\/li>\n\n\n<li>Linear \u900f\u904e GitHub Issue Sync \u628a\u7559\u8a00\u540c\u6b65\u5230 GitHub<\/li>\n\n\n<li>GitHub Action <code>claude.yml<\/code> \u5075\u6e2c\u5230 <code>@claude<\/code> \u2192 Claude Code \u958b\u65b0\u5206\u652f \u2192 \u6539 <code>.gd<\/code> \u2192 \u958b PR<\/li>\n\n\n<li><code>claude-code-review.yml<\/code> \u81ea\u52d5 review PR<\/li>\n\n\n<li><strong><code>deploy.yml<\/code> \u81ea\u52d5\u8dd1 Godot export \u2192 push \u5230 PR \u5206\u652f<\/strong><\/li>\n\n\n<li><strong>Cloudflare Pages \u5075\u6e2c PR \u5206\u652f\u8b8a\u52d5 \u2192 \u81ea\u52d5\u5efa preview URL<\/strong><\/li>\n\n\n<li>\u6211\u6253\u958b preview URL \u5be6\u969b\u8a66\u73a9<\/li>\n\n\n<li>OK \u5c31 merge \u2192 <code>deploy.yml<\/code> \u518d\u8dd1\u4e00\u6b21 \u2192 push \u5230 master \u2192 CF Pages \u90e8\u7f72\u6b63\u5f0f\u7248<\/li>\n\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">\u5f9e\u300c\u5728 Linear \u5beb\u4e00\u53e5\u4e2d\u6587\u300d\u5230\u300c\u7dda\u4e0a\u770b\u5230\u7d50\u679c\u300d\u7684\u904e\u7a0b\u4e2d\uff0c\u6211\u53ea\u9700\u8981\u505a\u5169\u4ef6\u4e8b\uff1a<strong>\u5beb\u9700\u6c42<\/strong> + <strong>\u9ede merge<\/strong>\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u503c\u5f97\u82b1\u9019 1.5 \u5c0f\u6642\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5f9e Linear @claude \u89f8\u767c\u3001Claude Code \u81ea\u52d5\u958b PR\u3001\u5230 GitHub Actions \u8dd1 Godot headless export \u4e26\u90e8\u7f72\u5230 Cloudflare Pages \u7684\u5b8c\u6574\u81ea\u52d5\u5316\u6d41\u7a0b\u3002\u8a18\u9304\u8e29\u904e\u7684\u4e09\u500b\u96f7\u8207\u6700\u5f8c\u53ef\u904b\u4f5c\u7684\u65b9\u6848\uff0c\u9644\u4e0a\u5411 AI \u554f\u554f\u984c\u7684\u6b63\u78ba\u59ff\u52e2\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rolpb_likes":0,"footnotes":""},"categories":[794],"tags":[798,797,799,796,795],"class_list":["post-800","post","type-post","status-publish","format-standard","hentry","category-cd","tag-ci-cd-2","tag-cloudflare-pages-2","tag-deploy","tag-github-actions-2","tag-godot"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":7}},"_links":{"self":[{"href":"https:\/\/blog.itsmygo.uk\/wordpress\/wp-json\/wp\/v2\/posts\/800","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.itsmygo.uk\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.itsmygo.uk\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.itsmygo.uk\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.itsmygo.uk\/wordpress\/wp-json\/wp\/v2\/comments?post=800"}],"version-history":[{"count":0,"href":"https:\/\/blog.itsmygo.uk\/wordpress\/wp-json\/wp\/v2\/posts\/800\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.itsmygo.uk\/wordpress\/wp-json\/wp\/v2\/media?parent=800"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.itsmygo.uk\/wordpress\/wp-json\/wp\/v2\/categories?post=800"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.itsmygo.uk\/wordpress\/wp-json\/wp\/v2\/tags?post=800"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}