Plugin Development Guide
Language
The recommended language for plugin code is TypeScript.
Writing Core Code
The core logic of the plugin can be written in JavaScript/TypeScript. If you need to use scripts in other languages, please call and execute them through JavaScript/TypeScript.
Development suggestion: First implement the most core functionality to ensure the plugin can run basically, then gradually iterate and add more features.
Example: Developing a Plugin with Node.js
import core from '@actions/core';
try {
const myInput = core.getInput('myInput'); // Get plugin input
const ref = process.env['ATOMGIT_REF']; // Get system variable
const result = `Hello ${pipelineId}, ${myInput}!`; // Plugin core logic
} catch (error) {
core.setFailed(`Action failed with error: ${error.message}`);
}
Parameter acquisition methods:
| Method | Purpose |
|---|---|
process.env[] | Get environment variable parameters |
core.getInput() | Get plugin input parameters |
Recommended Toolkits
GitHub Actions Toolkit is a recommended third-party toolkit used during development, providing modules such as @actions/core, @actions/io, @actions/exec, @actions/glob, and @actions/http-client, which can assist in plugin code development.
Log Output
Use the @actions/core library to output logs:
const core = require('@actions/core');
core.info('Starting action...');
core.warning('This is a warning message');
core.error('This is an error message');
| Method | Purpose |
|---|---|
core.info() | General log information |
core.warning() | Warning information |
core.error() | Error information |
Execution Status Feedback
- Normal execution completion: The task process returns
0 - An exception or error occurs: Modify the process return via
core.setFailed(), and the scheduling framework determines the task failure if a non-zero return is captured.
Result Output and Collection
The plugin task defines the output collection file path during runtime via the system variable $ATOMGIT_OUTPUT. The content output to this file will be collected by the system into the workflow step, job, and pipeline level output results.
Method One: Real-time Output via Log Keywords
This method collects and displays the output in real-time on the workflow, overwriting the same key and appending different keys.
log.info(`::set-output var=${outputkey}:${outputvalue}`)
Method Two: Batch Write Output (Recommended)
Collect all required outputs and write them to the official path defined by $ATOMGIT_OUTPUT, and report them uniformly after the plugin execution is successful:
export async function writeOutputContext(data: string) {
const filePath = core.getInputForEnv("ATOMGIT_OUTPUT");
log.info("outputFilePath is " + filePath);
if (!filePath) {
log.error(ErrorCode.INVALID_PARAM, {
cause: `Failed to get the upload report path: ATOMGIT_OUTPUT`,
causeZh: `获取输出路径失败: ATOMGIT_OUTPUT`,
});
return;
}
fs.appendFile(filePath, data, async (err) => {
if (err) {
log.error(ErrorCode.LOCAL_ERROR, {
cause: `Failed to write the report file.`,
causeZh: `写入output上报文件失败`,
});
return;
} else {
log.info("File written successfully!");
}
});
}
Plugin Summary Report Output
You can output custom Markdown format content for each Job (job), which will be directly displayed on the summary page of the Workflow run record. Using Job summaries, you can visualize and group specific content (such as test results). This way, people viewing the Workflow run results don't need to scroll through logs line by line to quickly grasp key information from this run (such as errors or failure messages).
You can append Markdown content generated in a Step to the file pointed to by the ATOMGIT_STEP_SUMMARY environment variable. It should be noted that the temporary file corresponding to ATOMGIT_STEP_SUMMARY is unique and independent for each Step.
After a Job completes execution, the summaries generated by all Steps under this Job are concatenated in order into a unified Job summary and displayed on the Workflow's run summary page. If multiple Jobs in a single run generate summaries, these summaries will be displayed in the order of the Jobs' completion times.
Adding a Job summary example:
echo "### Hello world! :rocket:" >> $ATOMGIT_STEP_SUMMARY
Multi-line Markdown Content
If you need to write multi-line Markdown content, you can continuously use the >> append operator within the current Step. Each time an append operation is executed, the system automatically adds a newline character.
Example of multi-line Markdown content:
- name: Generate list using Markdown
run: |
echo "This is the lead in sentence for the list" >> $ATOMGIT_STEP_SUMMARY
echo "" >> $ATOMGIT_STEP_SUMMARY # This is an empty line
echo "- Lets add a bullet point" >> $ATOMGIT_STEP_SUMMARY
echo "- Lets add a second bullet point" >> $ATOMGIT_STEP_SUMMARY
echo "- How about a third one?" >> $ATOMGIT_STEP_SUMMARY
Post-processing After Plugin Execution (post)
The post script (recommended to be named post.js) provides logic for the scheduling service to call after the plugin, used for cleaning up the site and executing post-processing logic.
Trigger mechanism:
| Trigger method | Description |
|---|---|
| Manually stop the workflow | The user clicks to stop the workflow, and the scheduling service calls it actively. |
| Naturally called after the plugin completes | The plugin developer needs to actively listen for termination signals in main and call it. |
Example - Listening for termination signals in main:
import {post} from "./stop";
async function run() {
// Capture SIGINT signal
process.on('SIGINT', () => {
post();
process.exit(0);
});
// Plugin main logic...
log.info("process has been started,press 'Ctrl C' to stop.");
setInterval(() => {
log.info("process running...");
}, 1000);
}