Javascript/html 在 gitlab wiki 页面?

Javascript/html in gitlab wiki page?

恐怕我真的不知道该怎么做 - 我想在 Gitlab Wiki 页面中使用变量。这完全可以使用 html 吗?我可以在页面上 运行 脚本吗?

例如,关于在 html 中使用 javascript 变量的 - 这样的事情可能吗?

对于我的具体示例,我想要一个带有 table 的页面,其中第一列是数字,我想取最大值并将其显示在页面顶部。因此,例如 table 可能有这样的行:

1   X
22  Y
15  Z

所以在页面顶部我会显示 "largest number is 22"。这有意义吗?

您的 Wikipage 中不能有脚本,因为它们会清理 HTML(查看它们允许的内容 here). To do what you want, you could generate that page in Gitlab-CI as part of your project's deploy pipeline, using whatever rendering engine and putting that variable in there, and update it automatically using Gitlab's Wiki APIs

如何

我创建了一个演示 NodeJS 项目 here, which, when I push to the master branch, auto-generates the Wiki pages。您可以查看代码以了解其工作原理。

此示例应用公开了一个函数来获取库存水果和数量列表。我们会自动将该数据添加到 Wiki 中。

第 1 步 - 创建页面模板

您可以为 Wiki 页面的项目添加模板。在我的示例中,我使用了 MustacheJS。我将所有内容都放在 wiki 文件夹中(请参阅步骤 5 末尾的文件夹结构)。您的模板可能如下所示:

wiki/templates/home.mst

# Welcome to the supermarket

The biggest quantity we have in stock is for **{{topProduct.label}}**,
with a total of **{{topProduct.stock}}**!

|   Fruit   |   Quantity   |
|-----------|--------------|
{{#inventory}}
| {{label}} | {{stock}} |
{{/inventory}}

在此示例中,数据将来自项目代码本身。

第 2 步 - 构建您的页面

Note: The scripts I wrote as a demo use axios to make requests to the Gitlab API, mustache to render the pages, and qs to format the data as a query string before posting it to Gitlab. You can use other ones or install them as dev dependencies: npm install --save-dev axios mustache qs

创建一个 js 文件,它将从您的应用程序获取数据,并将模板呈现到 build 目录中。像这样:

wiki/build.js

const fs = require('fs');
const Mustache = require('mustache');
const myApp = require('../src/index.js');
const inventory = myApp.getInventory();

// Get the Mustache template
const homeTemplate = fs.readFileSync(__dirname + '/templates/home.mst', 'utf-8');

// Get the fruit with the highest quantity
const topProduct = inventory.reduce((acc, curr) => {
  if (acc === null || curr.stock > acc.stock) {
    return curr;
  } else {
    return acc;
  }
}, null);

// Render the page using your variables
const homeContent = Mustache.render(homeTemplate, { inventory, topProduct });

// Write the file in a build directory
const buildDir = __dirname + '/../build';
if (!fs.existsSync(buildDir)) {
  fs.mkdirSync(buildDir);
}

fs.writeFileSync(buildDir + '/home.md', homeContent);

然后在您的 package.json 中,向 运行 该脚本添加命令:

"scripts": {
    // ...
    "wiki:build": "node wiki/build.js"
  }

第 3 步 - 部署您的 Wiki 页面

创建一个将页面上传到您的 Wiki 的脚本。如果您还使用 NodeJS,这可能会在没有太多修改的情况下按原样工作。

wiki/deploy.js

const fs = require('fs');
const Axios = require('axios');
const qs = require('qs');

const config = {
  gitlabBaseUrl: 'https://gitlab.com', // Update this if you're on a private Gitlab
  projectId: process.env.CI_PROJECT_ID, // Provided by Gitlab-CI
  privateToken: process.env.WIKI_DEPLOY_TOKEN, // Added through Gitlab interface
  buildDir: __dirname + '/../build'
};

const axios = Axios.create({
  baseURL: config.gitlabBaseUrl,
  headers: { 'Private-Token': config.privateToken, Accept: 'application/json' }
});

(async function deploy() {
  const existingPages = await getExistingWikiPages();
  const updatedPages = getUpdatedPages();
  // Pages which existed but are no longer in the build (obsolete)
  const pagesToDelete = existingPages.filter(p1 => updatedPages.every(p2 => p2.slug !== p1.slug));
  // Pages which didn't exist before
  const pagesToCreate = updatedPages.filter(p1 => existingPages.every(p2 => p2.slug !== p1.slug));
  // Pages which already exist
  const pagesToUpdate = updatedPages.filter(p1 => existingPages.some(p2 => p2.slug === p1.slug));

  console.log(
    `Found ${pagesToDelete.length} pages to delete, ${pagesToCreate.length} pages to create, ${pagesToUpdate.length} pages to update.`
  );
  for (let page of pagesToDelete) {
    await deletePage(page);
  }
  for (let page of pagesToCreate) {
    await createPage(page);
  }
  for (let page of pagesToUpdate) {
    await updatePage(page);
  }
  console.log('Deploy complete!');
})();

function getExistingWikiPages() {
  return axios.get(`/api/v4/projects/${config.projectId}/wikis`).then(res => res.data);
}

function getUpdatedPages() {
  const files = fs.readdirSync(config.buildDir);
  return files.map(file => {
    const name = file // Remove the file extension
      .split('.')
      .slice(0, -1)
      .join('.');
    return {
      format: 'markdown', // You could make this depend on the file extension
      slug: name,
      title: name,
      content: fs.readFileSync(`${config.buildDir}/${file}`, 'utf-8')
    };
  });
}

function deletePage(page) {
  console.log(`Deleting ${page.slug}...`);
  return axios.delete(`/api/v4/projects/${config.projectId}/wikis/${page.slug}`);
}

function createPage(page) {
  console.log(`Creating ${page.slug}...`);
  return axios.post(`/api/v4/projects/${config.projectId}/wikis`, qs.stringify(page));
}

function updatePage(page) {
  console.log(`Updating ${page.slug}...`);
  return axios.put(`/api/v4/projects/${config.projectId}/wikis/${page.slug}`, qs.stringify(page));
}

在顶部的config中,你需要指定你的Gitlab使用的是哪个URL。 CI_PROJECT_ID会由Gitlab-CI自己提供,作为环境变量。 WIKI_DEPLOY_TOKEN,然而,不会。在步骤 4 中设置它。

然后在您的 package.json 中,向 运行 该脚本添加命令:

"scripts": {
    // ...
    "wiki:build": "node wiki/build.js",
    "wiki:deploy": "node wiki/deploy.js"
  }

注意:此示例将删除过时页面,并根据它在构建文件夹中找到的文件和 Wiki 已包含的文件更新或创建新页面。如果你还想有附件(图片),你还需要使用 this API

第 4 步 - 设置私人令牌 WIKI_DEPLOY_TOKEN

为此,您需要点击右上角的个人资料图片> 设置。然后在左侧菜单中,Access Tokens,并创建一个范围为 api 的令牌。名字并不重要。现在复制此令牌,因为它只会显示一次。

然后,转到您的项目。在左侧菜单中,单击 设置 > CI/CD。展开 Variables 部分,并使用之前复制的标记创建一个名为 WIKI_DEPLOY_TOKEN 的变量,将其 Masked 使其不出现在任何日志中,并且保存变量:

这将使该令牌仅在您的管道中可用,作为环境变量。

第 5 步 - 创建管道

如果您还没有管道,您需要做的就是在项目的根目录下创建一个 .gitlab-ci.yml 文件。声明一个 generate_wiki 阶段:

.gitlab-ci.yml

stages:
  # - tests
  # - deploy
  # ...
  - generate_wiki

generate_wiki:
  image: node:10
  stage: generate_wiki
  script:
    - npm install
    - npm run wiki:build  # build the wiki in a directory
    - npm run wiki:deploy # update it in Gitlab
  only:
    - master # Only when merging or pushing to master branch


# ... rest of your pipeline ...

如您所见,我们使用了在步骤 2 和 3 中声明的命令 wiki:buildwiki:deploy

现在,您的项目结构应该如下所示:

/
├───src
│    └── index.js
├───wiki
│    ├── templates
│    │    └── home.mst
│    ├── build.js
│    └── deploy.js
├── .gitlab-ci.yml
└── package.json

第 6 步 - 掌握,享受魔法

推送后,如果一切顺利,您可以点击左侧菜单中的CI/CD,您应该会看到您的管道运行ning:

如果单击小圆圈,您应该会看到日志:

如果您访问您的 Wiki 页面,它们应该会自动更新: