You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从自托管私有Gitlab的Markdown页面同步内容至WordPress文章

自托管Gitlab到WP Engine WordPress的文档同步方案

针对你遇到的私有Gitlab无法被WP插件访问、WP Engine限制服务器安装内容的问题,以下是几个无依赖、易实现的同步方案:

方案1:Gitlab CI/CD + WordPress REST API(推荐)

完全在Gitlab侧执行同步,不需要WP服务器安装任何额外工具,利用Gitlab的CI/CD流水线触发推送,通过WP官方REST API更新文章。

操作步骤

  1. WordPress侧配置API权限

    • WP 5.6及以上版本内置「应用密码」功能,在用户个人资料页面生成一个具有「编辑文章」权限的应用密码,记录用户名和密码。
    • 确保WP REST API处于启用状态(WP默认启用,WP Engine不会禁用该功能)。
  2. 编写Gitlab CI/CD流水线脚本
    在Gitlab文档仓库根目录创建.gitlab-ci.yml,设置分支推送时自动执行同步:

    stages:
      - sync_to_wordpress
    
    sync_job:
      stage: sync_to_wordpress
      image: pandoc/core:latest  # 自带Markdown转HTML工具
      before_script:
        - apk add --no-cache curl jq  # 安装HTTP请求和JSON处理工具
      script:
        - |
          # 遍历仓库中所有Markdown文件(可自行调整路径)
          for md_file in ./docs/*.md; do
            # 提取Markdown标题(取第一个一级标题)
            POST_TITLE=$(head -n1 "$md_file" | sed 's/^# //')
            # 转换Markdown为HTML
            POST_CONTENT=$(pandoc -f markdown -t html "$md_file")
            # 生成文章slug(用文件名转小写、空格转连字符)
            POST_SLUG=$(basename "$md_file" .md | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
    
            # 检查WP中是否已存在该文章
            EXISTING_POST_ID=$(curl -s -u "${WP_USERNAME}:${WP_APP_PASSWORD}" \
              "${WP_SITE_URL}/wp-json/wp/v2/posts?slug=${POST_SLUG}" | jq '.[0].id')
    
            if [ "$EXISTING_POST_ID" != "null" ]; then
              # 更新已有文章
              curl -X PUT -u "${WP_USERNAME}:${WP_APP_PASSWORD}" \
                "${WP_SITE_URL}/wp-json/wp/v2/posts/${EXISTING_POST_ID}" \
                -H "Content-Type: application/json" \
                -d '{
                  "title": "'"${POST_TITLE}"'",
                  "content": "'"${POST_CONTENT}"'",
                  "status": "publish"
                }'
            else
              # 创建新文章
              curl -X POST -u "${WP_USERNAME}:${WP_APP_PASSWORD}" \
                "${WP_SITE_URL}/wp-json/wp/v2/posts" \
                -H "Content-Type: application/json" \
                -d '{
                  "title": "'"${POST_TITLE}"'",
                  "content": "'"${POST_CONTENT}"'",
                  "slug": "'"${POST_SLUG}"'",
                  "status": "publish"
                }'
            fi
          done
      only:
        - main  # 指定触发同步的分支
      variables:
        WP_SITE_URL: "https://your-wp-site.com"  # 替换为你的WP站点地址
        # 以下变量建议在Gitlab仓库CI/CD设置中添加(避免硬编码)
        # WP_USERNAME: "你的WP用户名"
        # WP_APP_PASSWORD: "生成的应用密码"
    
    • 登录Gitlab仓库,进入「设置」→「CI/CD」→「变量」,添加WP_USERNAME和WP_APP_PASSWORD两个保密变量。

方案2:Gitlab服务器定时任务 + WP-CLI

利用你已在Gitlab服务器安装的WP-CLI,结合定时任务定期拉取仓库更新并同步到WP。

操作步骤

  1. Gitlab服务器拉取文档仓库

    • 在Gitlab服务器上生成SSH密钥,添加到Gitlab仓库的「部署密钥」中(赋予读取权限)。
    • 克隆私有文档仓库到本地目录:git clone git@your-gitlab-server:group/repo.git /path/to/docs-repo
  2. 编写同步脚本
    创建wp-sync.sh脚本(需安装pandoc用于Markdown转HTML):

    #!/bin/bash
    REPO_DIR="/path/to/docs-repo"
    WP_SITE="https://your-wp-site.com"
    WP_USER="你的WP用户名"
    WP_PASS="你的WP应用密码"
    
    # 拉取仓库最新内容
    cd $REPO_DIR
    git pull origin main
    
    # 遍历Markdown文件同步
    for md_file in ./docs/*.md; do
      POST_TITLE=$(head -n1 "$md_file" | sed 's/^# //')
      POST_CONTENT=$(pandoc -f markdown -t html "$md_file")
      POST_SLUG=$(basename "$md_file" .md | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
    
      # 检查文章是否存在
      EXISTING_ID=$(wp --url=$WP_SITE --user=$WP_USER --password=$WP_PASS post list --slug=$POST_SLUG --field=ID)
    
      if [ -n "$EXISTING_ID" ]; then
        wp --url=$WP_SITE --user=$WP_USER --password=$WP_PASS post update $EXISTING_ID \
          --post_title="$POST_TITLE" --post_content="$POST_CONTENT" --post_status=publish
      else
        wp --url=$WP_SITE --user=$WP_USER --password=$WP_PASS post create \
          --post_title="$POST_TITLE" --post_content="$POST_CONTENT" --post_name="$POST_SLUG" --post_status=publish
      fi
    done
    
    • 给脚本添加执行权限:chmod +x wp-sync.sh
  3. 设置定时任务
    编辑crontab:crontab -e,添加定时规则(比如每天凌晨1点同步):

    0 1 * * * /path/to/wp-sync.sh >> /var/log/wp-sync.log 2>&1
    

方案3:Gitlab Webhook + WP自定义端点

通过Gitlab Webhook触发WP侧的同步逻辑,适合需要实时同步的场景,仅需在WP侧添加少量代码和轻量依赖。

操作步骤

  1. Gitlab配置Webhook

    • 进入仓库「设置」→「Webhooks」,添加WP端点URL:https://your-wp-site.com/wp-json/sync/v1/gitlab
    • 设置触发事件为「Push events」,添加一个自定义密钥(比如GITLAB_WEBHOOK_SECRET),保存。
  2. WP侧添加同步逻辑

    • 在当前主题的functions.php中添加以下代码(需上传Parsedown.php轻量Markdown解析器到主题目录):
    // 注册REST API端点
    add_action('rest_api_init', function () {
        register_rest_route('sync/v1', '/gitlab', [
            'methods' => 'POST',
            'callback' => 'sync_gitlab_docs',
            'permission_callback' => function () {
                // 验证Webhook签名
                $secret = 'GITLAB_WEBHOOK_SECRET';
                $request_signature = $_SERVER['HTTP_X_GITLAB_TOKEN'] ?? '';
                if (!hash_equals($secret, $request_signature)) {
                    return new WP_Error('invalid_signature', '无效签名', ['status' => 403]);
                }
                return true;
            }
        ]);
    });
    
    function sync_gitlab_docs($request) {
        $payload = $request->get_json_params();
        $gitlab_token = '你的Gitlab个人访问令牌'; // 需有仓库读取权限
        $project_path = urlencode($payload['project']['path_with_namespace']);
    
        // 处理推送的Markdown文件
        foreach ($payload['commits'] as $commit) {
            foreach (array_merge($commit['added'], $commit['modified']) as $file) {
                if (pathinfo($file, PATHINFO_EXTENSION) !== 'md') continue;
    
                // 通过Gitlab API获取文件内容
                $file_api_url = "https://your-gitlab-server/api/v4/projects/{$project_path}/repository/files/" . urlencode($file) . "?ref=main&private_token={$gitlab_token}";
                $api_response = wp_remote_get($file_api_url);
                if (is_wp_error($api_response)) continue;
    
                $file_data = json_decode(wp_remote_retrieve_body($api_response), true);
                $md_content = base64_decode($file_data['content']);
    
                // 转换Markdown为HTML
                require_once get_template_directory() . '/Parsedown.php';
                $parsedown = new Parsedown();
                $html_content = $parsedown->text($md_content);
    
                // 提取标题和生成slug
                $title = preg_match('/^# (.*)$/m', $md_content, $matches) ? $matches[1] : pathinfo($file, PATHINFO_FILENAME);
                $slug = sanitize_title($title);
    
                // 更新或创建文章
                $existing_post = get_posts([
                    'name' => $slug,
                    'post_type' => 'post',
                    'post_status' => 'publish',
                    'numberposts' => 1
                ]);
    
                if ($existing_post) {
                    wp_update_post([
                        'ID' => $existing_post[0]->ID,
                        'post_title' => $title,
                        'post_content' => $html_content
                    ]);
                } else {
                    wp_insert_post([
                        'post_title' => $title,
                        'post_content' => $html_content,
                        'post_name' => $slug,
                        'post_status' => 'publish'
                    ]);
                }
            }
        }
        return ['status' => '同步完成'];
    }
    
    • 下载Parsedown.php后上传到主题根目录。

内容的提问来源于stack exchange,提问作者jrod091

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:05:59