欧博官网Javascript/html in gitlab wiki page?
You cannot have a script in your Wikipage, since they sanitize the HTML (See what they allow ). 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.
How toI created a demo NodeJS project here, which, when I push to the master branch, auto-generates the Wiki pages. You can look at the code to see how it works.
This example app exposes a function to get a list of fruit and quantities in stock. We'll automatically add that data in the Wiki.
Step 1 - Create page templatesYou can add templates to your project for your Wiki pages. In my example, I used MustacheJS. And I put everything in a wiki folder (see folder structure at the end of step 5). Your template can look something like this:
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}}In this example, the data will come from the project code itself.
Step 2 - Build your pagesNote: 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
Create a js file which will get the data from your app, and render the templates into a build directory. Something like this:
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);And in your package.json, add a command to run that script:
"scripts": { // ... "wiki:build": "node wiki/build.js" } Step 3 - Deploy your Wiki pagesCreate a script which will upload the pages to your Wiki. This may work as-is without much modification, if you're also using 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)); }In the config at the top, you need to specify which URL your Gitlab is using. CI_PROJECT_ID will be provided by Gitlab-CI itself as an environment variable. WIKI_DEPLOY_TOKEN, however, will not. Set it up in step 4.
And in your package.json, add a command to run that script:
"scripts": { // ... "wiki:build": "node wiki/build.js", "wiki:deploy": "node wiki/deploy.js" }Note: This example will delete obsolete pages, and update or create new ones depending on files it finds in the build folder and the ones the Wiki already contains. If you want to have attachments as well (images), you'll need to make use of also.
Step 4 - Setup a private token WIKI_DEPLOY_TOKENFor this, you'll need to click on your profile picture at the top right corner > Settings. Then in the left menu, Access Tokens, and create a token with the api scope. The name does not matter. Copy this token now, since it will only be shown once.
Then, go to your project. In the menu on the left, click Settings > CI/CD. Expand the Variables section, and use the previously copied token to create a variable called WIKI_DEPLOY_TOKEN, make it Masked so that it does not appear in any logs, and Save variables:
This will make that token available only in your pipelines, as an environment variable.
Step 5 - Create your pipelineIf you don't already have a pipeline, all you need to do is create a .gitlab-ci.yml file at the root of your project. Declare a generate_wiki stage:
.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 ...As you can see, we use the commands wiki:build and wiki:deploy declared in steps 2 and 3.
Now, your project structure should look something like this:
/ ├───src │ └── index.js ├───wiki │ ├── templates │ │ └── home.mst │ ├── build.js │ └── deploy.js ├── .gitlab-ci.yml └── package.json Step 6 - Push to master, and enjoy the magicAfter pushing, if everything went right, you can click on CI/CD in the left menu, and you should see your pipeline running:
If you click on the little circle, you should see the logs:
And if you go to your Wiki pages, they should be up to date, automagically: