pipeline-plugin-development
npx skills add https://github.com/tencentblueking/bk-ci --skill pipeline-plugin-development
Agent 安装分布
Skill 文档
æµæ°´çº¿æä»¶å¼å宿´æå
模åå®ä½: æ¬æå详ç»ä»ç»èç¾ï¼BK-CIï¼æµæ°´çº¿æä»¶çå¼åè§èãé ç½®æ¹æ³ãå¤è¯è¨å®ç°ç¤ºä¾ãå叿µç¨åè°è¯æå·§ï¼å¸®å©å¼åè å¿«é䏿æä»¶å¼åã
ä¸ãæä»¶å¼åæ¦è¿°
1.1 ä»ä¹æ¯æµæ°´çº¿æä»¶
æµæ°´çº¿æä»¶ï¼Atomï¼æ¯èç¾æµæ°´çº¿ä¸çæå°æ§è¡åå ï¼ç¨äºå®æç¹å®çæå»ºä»»å¡ï¼å¦ä»£ç æåãç¼è¯ãæµè¯ãé¨ç½²çã
1.2 æ¯æçå¼åè¯è¨
| è¯è¨ | æ¨è度 | SDK |
|---|---|---|
| Java | âââââ | java-atom-sdk |
| Python | ââââ | python-atom-sdk |
| NodeJS | âââ | @tencent/nodejs_atom_sdk |
| Golang | âââ | golang-atom-sdk |
1.3 æä»¶å¼åæµç¨
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â æä»¶å¼å宿´æµç¨ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â â
â 1. åå§åæä»¶ 2. å¼åæä»¶ 3. å叿件 â
â ââââââââââââââââ ââââââââââââââââ ââââââââââââââââ â
â â ç»å½å·¥ä½å° â ââ⺠â ç¼å task.jsonâ âââº â æäº¤æå»º â â
â â æ°å¢æä»¶ â â å¼åä¸å¡é»è¾ â â æµè¯éªè¯ â â
â â å
é代ç åº â â æ¬å°è°è¯ â â å®¡æ ¸åå¸ â â
â ââââââââââââââââ ââââââââââââââââ ââââââââââââââââ â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
äºãtask.json é ç½®è§è
2.1 æ´ä½ç»æ
{
"atomCode": "myAtom", // æä»¶å¯ä¸æ è¯ï¼å¿
å¡«ï¼
"defaultLocaleLanguage": "zh_CN", // é»è®¤è¯è¨ï¼éå¿
å¡«ï¼
"execution": { // æ§è¡é
ç½®ï¼å¿
å¡«ï¼
"language": "python",
"demands": [],
"target": "demo"
},
"inputGroups": [], // è¾å
¥å段åç»ï¼éå¿
å¡«ï¼
"input": {}, // è¾å
¥å段å®ä¹ï¼å¿
å¡«ï¼
"output": {}, // è¾åºå段å®ä¹ï¼éå¿
å¡«ï¼
"config": {} // æä»¶æ§å¶ç¹æ§ï¼éå¿
å¡«ï¼
}
注æ: task.json å 容é¿åº¦æå¤§ä¸º 64KB
2.2 execution æ§è¡é ç½®
| 屿§å | 说æ | æ ¼å¼ | å¿ å¡« |
|---|---|---|---|
language |
å¼åè¯è¨ | å符串 | æ¯ |
target |
æ§è¡å ¥å£å½ä»¤ | å符串 | æ¯ |
demands |
æ§è¡åç½®ä¾èµå½ä»¤ | æ°ç» | å¦ |
runtimeVersion |
è¿è¡æ¶çæ¬ | å符串 | å¦ |
finishKillFlag |
æ§è¡å®æåæ¯å¦æè¿ç¨ | å¸å° | å¦ |
os |
æä½ç³»ç»ç¸å ³é ç½® | æ°ç» | å¦ |
2.2.1 runtimeVersion é ç½®å¼
| è¯è¨ | é ç½®å¼ | 夿³¨ |
|---|---|---|
| python | python2 |
é»è®¤ |
| python | python3 |
æ¨è |
| nodejs | 10.* ~ 18.* |
é»è®¤ 10.* |
| java | 8 |
é»è®¤ |
| java | 17 |
æ°çæ¬ |
2.2.2 os 跨平å°é 置示ä¾
{
"execution": {
"language": "golang",
"os": [
{
"osName": "linux",
"osArch": "amd64",
"target": "./app",
"demands": [],
"defaultFlag": true
},
{
"osName": "windows",
"osArch": "386",
"target": "./app.exe",
"demands": [],
"defaultFlag": false
},
{
"osName": "darwin",
"osArch": "arm64",
"target": "./app",
"demands": [],
"defaultFlag": false
}
]
}
}
2.3 input è¾å ¥å段é ç½®
2.3.1 æ¯æç UI ç»ä»¶ç±»å
| ç»ä»¶ type | ç»ä»¶åç§° | è·åå°ç弿 ¼å¼ |
|---|---|---|
vuex-input |
åè¡ææ¬æ¡ | å符串 |
vuex-textarea |
å¤è¡ææ¬æ¡ | å符串 |
atom-ace-editor |
代ç ç¼è¾æ¡ | å符串 |
selector |
䏿æ¡ï¼åªéä¸è¾å ¥ï¼ | åé: å符串; å¤é: ["str1", "str2"] |
select-input |
å¯è¾å ¥ä¸ææ¡ | åä¸ |
devops-select |
å¯è¾å ¥ä¸ææ¡ï¼ä» åéï¼ | åä¸ |
atom-checkbox-list |
å¤éæ¡å表 | ["id1", "id2"] |
atom-checkbox |
å¤éæ¡ï¼å¸å°ï¼ | "true" æ "false" |
enum-input |
åé Radio | å符串 |
time-picker |
æ¥æéæ©å¨ | å符串 |
staff-input |
人åéæ©å¨ï¼é¡¹ç®æåï¼ | å符串 |
company-staff-input |
人åéæ©å¨ï¼å ¬å¸æåï¼ | å符串 |
tips |
æç¤ºä¿¡æ¯ | æ |
parameter |
ä¸å®åæ°å表 | JSON å符串 |
dynamic-parameter |
卿忰å表 | JSON å符串 |
dynamic-parameter-simple |
卿忰ï¼ç®æçï¼ | JSON å符串 |
2.3.2 è¾å ¥åæ®µå ¬å ±å±æ§
| 屿§å | 说æ | æ ¼å¼ | å¿ å¡« |
|---|---|---|---|
label |
䏿å | å符串 | æ¯ |
type |
ç»ä»¶ç±»å | å符串 | æ¯ |
default |
é»è®¤å¼ | æ ¹æ®ç»ä»¶ç±»å | å¦ |
placeholder |
å ä½æç¤º | å符串 | å¦ |
groupName |
æå±åç» | å符串 | å¦ |
desc |
åæ®µè¯´æ | å符串 | å¦ |
required |
æ¯å¦å¿ å¡« | å¸å° | å¦ |
disabled |
æ¯å¦ç¦ç¨ | å¸å° | å¦ |
hidden |
æ¯å¦éè | å¸å° | å¦ |
isSensitive |
æ¯å¦ææä¿¡æ¯ | å¸å° | å¦ |
rely |
æ¡ä»¶æ¾ç¤º/éè | 对象 | å¦ |
rule |
弿 ¡éªè§å | 对象 | å¦ |
2.3.3 宿´è¾å ¥å段示ä¾
{
"input": {
"repositoryUrl": {
"label": "代ç åºå°å",
"type": "vuex-input",
"placeholder": "请è¾å
¥ Git ä»åºå°å",
"desc": "æ¯æ HTTP/HTTPS/SSH åè®®",
"required": true,
"rule": {
"regex": "^(https?|git)://"
}
},
"branch": {
"label": "忝",
"type": "select-input",
"default": "master",
"optionsConf": {
"searchable": true,
"multiple": false,
"url": "/repository/api/user/repositories/{projectId}/branches",
"paramId": "name",
"paramName": "name"
}
},
"enableCache": {
"label": "",
"type": "atom-checkbox",
"text": "å¯ç¨ç¼å",
"default": true
},
"buildType": {
"label": "æå»ºç±»å",
"type": "enum-input",
"default": "release",
"list": [
{"label": "Debug", "value": "debug"},
{"label": "Release", "value": "release"}
]
},
"advancedOptions": {
"label": "é«çº§é项",
"type": "vuex-input",
"rely": {
"operation": "AND",
"expression": [
{"key": "enableCache", "value": true}
]
}
}
}
}
2.4 output è¾åºå段é ç½®
{
"output": {
"buildResult": {
"type": "string",
"description": "æå»ºç»æ",
"isSensitive": false
},
"artifactPath": {
"type": "artifact",
"description": "æå»ºäº§ç©è·¯å¾"
},
"reportHtml": {
"type": "report",
"description": "æµè¯æ¥å"
}
}
}
è¾åºç±»å说æ:
| ç±»å | 说æ | éå¶ |
|---|---|---|
string |
å符串åé | é¿åº¦ä¸è¶ è¿ 4KB |
artifact |
æä»¶æä»¶ | èªå¨å½æ¡£å°ä»åº |
report |
æ¥åæä»¶ | æ¯æ HTML 渲æ |
2.5 config æä»¶æ§å¶ç¹æ§
{
"config": {
"canPauseBeforeRun": false,
"defaultTimeout": 60,
"defaultFailPolicy": "MANUALLY_CONTINUE",
"defaultRetryPolicy": ["AUTO_RETRY"],
"retryTimes": 3
}
}
2.6 å ç½®åé
| åéå | 说æ |
|---|---|
{projectId} |
项ç®è±æ ID |
{pipelineId} |
æµæ°´çº¿ ID |
{buildId} |
æå»º ID |
ä¸ãå¤è¯è¨å¼å示ä¾
3.1 Python æä»¶å¼å
3.1.1 ç®å½ç»æ
my-python-atom/
âââ task.json
âââ setup.py
âââ requirements.txt
âââ demo/
âââ __init__.py
âââ command_line.py
3.1.2 task.json
{
"atomCode": "myPythonAtom",
"execution": {
"language": "python",
"demands": [],
"target": "demo"
},
"input": {
"inputDemo": {
"label": "è¾å
¥ç¤ºä¾",
"type": "vuex-input",
"required": true
}
},
"output": {
"outputDemo": {
"type": "string",
"description": "è¾åºç¤ºä¾"
}
}
}
3.1.3 setup.py
from setuptools import setup, find_packages
setup(
name="myPythonAtom",
packages=find_packages(),
install_requires=["python-atom-sdk"],
entry_points={
"console_scripts": [
"demo = demo.command_line:main"
]
}
)
3.1.4 command_line.py
# -*- coding: utf-8 -*-
import python_atom_sdk as sdk
def main():
sdk.log.info("æä»¶å¼å§æ§è¡")
# è·åè¾å
¥åæ°
input_params = sdk.get_input()
input_demo = input_params.get("inputDemo", "")
sdk.log.info(f"è¾å
¥åæ°: {input_demo}")
# ä¸å¡é»è¾å¤ç
result = f"å¤çç»æ: {input_demo}"
# 设置è¾åº
output_data = {
"status": sdk.status.SUCCESS,
"message": "æ§è¡æå",
"errorCode": 0,
"type": sdk.output_template_type.DEFAULT,
"data": {
"outputDemo": {
"type": sdk.output_field_type.STRING,
"value": result
}
}
}
sdk.set_output(output_data)
sdk.log.info("æä»¶æ§è¡å®æ")
exit(0)
if __name__ == "__main__":
main()
3.2 Java æä»¶å¼å
3.2.1 ç®å½ç»æ
my-java-atom/
âââ task.json
âââ pom.xml
âââ settings.xml
âââ src/main/
âââ java/com/example/atom/
â âââ AtomParam.java
â âââ DemoAtom.java
âââ resources/META-INF/services/
âââ com.tencent.bk.devops.atom.spi.TaskAtom
3.2.2 task.json
{
"atomCode": "myJavaAtom",
"defaultLocaleLanguage": "zh_CN",
"execution": {
"language": "java",
"minimumVersion": "1.8",
"demands": [],
"target": "java -jar myJavaAtom-jar-with-dependencies.jar"
},
"input": {
"desc": {
"label": "æè¿°",
"type": "vuex-input",
"placeholder": "请è¾å
¥æè¿°ä¿¡æ¯",
"required": true
}
},
"output": {
"testResult": {
"type": "string",
"description": "æ§è¡ç»æ"
}
}
}
3.2.3 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.tencent.bk.devops.atom</groupId>
<artifactId>sdk-dependencies</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>myJavaAtom</artifactId>
<version>1.0.0</version>
<properties>
<sdk.version>1.1.58</sdk.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.tencent.bk.devops.atom</groupId>
<artifactId>java-atom-sdk</artifactId>
<version>${sdk.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.2.4 AtomParam.java
package com.example.atom;
import com.tencent.bk.devops.atom.pojo.AtomBaseParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class AtomParam extends AtomBaseParam {
private String desc;
}
3.2.5 DemoAtom.java
package com.example.atom;
import com.tencent.bk.devops.atom.AtomContext;
import com.tencent.bk.devops.atom.common.Status;
import com.tencent.bk.devops.atom.pojo.AtomResult;
import com.tencent.bk.devops.atom.pojo.StringData;
import com.tencent.bk.devops.atom.spi.AtomService;
import com.tencent.bk.devops.atom.spi.TaskAtom;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@AtomService(paramClass = AtomParam.class)
public class DemoAtom implements TaskAtom<AtomParam> {
private static final Logger logger = LoggerFactory.getLogger(DemoAtom.class);
@Override
public void execute(AtomContext<AtomParam> atomContext) {
// è·ååæ°
AtomParam param = atomContext.getParam();
AtomResult result = atomContext.getResult();
logger.info("è¾å
¥åæ°: {}", param.getDesc());
// åæ°æ ¡éª
if (param.getDesc() == null || param.getDesc().isEmpty()) {
result.setStatus(Status.failure);
result.setMessage("æè¿°ä¸è½ä¸ºç©º");
return;
}
// ä¸å¡é»è¾
logger.groupStart("æ§è¡ä»»å¡");
String output = "å¤çç»æ: " + param.getDesc();
logger.info(output);
logger.groupEnd("æ§è¡ä»»å¡");
// 设置è¾åº
result.setStatus(Status.success);
result.getData().put("testResult", new StringData(output));
}
}
3.2.6 SPI é ç½®æä»¶
src/main/resources/META-INF/services/com.tencent.bk.devops.atom.spi.TaskAtom:
com.example.atom.DemoAtom
3.3 NodeJS æä»¶å¼å
3.3.1 ç®å½ç»æ
my-nodejs-atom/
âââ task.json
âââ package.json
âââ rollup.config.js
âââ index.js
âââ .gitignore
3.3.2 task.json
{
"atomCode": "myNodejsAtom",
"execution": {
"language": "nodejs",
"demands": [],
"target": "node dist/bundle.js"
},
"input": {
"inputDemo": {
"label": "è¾å
¥ç¤ºä¾",
"type": "vuex-input",
"required": true
}
},
"output": {
"outputDemo": {
"type": "string",
"description": "è¾åºç¤ºä¾"
}
}
}
3.3.3 package.json
{
"name": "myNodejsAtom",
"version": "1.0.0",
"main": "./dist/bundle.js",
"dependencies": {
"@tencent/nodejs_atom_sdk": "^1.1.12"
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"rollup": "^1.16.2",
"rollup-plugin-babel": "^4.3.3"
}
}
3.3.4 rollup.config.js
import babel from 'rollup-plugin-babel'
export default {
input: 'index.js',
output: {
file: 'dist/bundle.js',
format: 'cjs'
},
plugins: [babel()]
}
3.3.5 index.js
import {
getInputParams,
setOutput,
BK_ATOM_STATUS,
BK_OUTPUT_TEMPLATE_TYPE
} from '@tencent/nodejs_atom_sdk'
const params = getInputParams()
console.log('è¾å
¥åæ°:', params)
const inputDemo = params.inputDemo || ''
const result = `å¤çç»æ: ${inputDemo}`
setOutput({
"type": BK_OUTPUT_TEMPLATE_TYPE.DEFAULT,
"status": BK_ATOM_STATUS.SUCCESS,
"data": {
"outputDemo": {
"type": "string",
"value": result
}
}
})
3.4 Golang æä»¶å¼å
3.4.1 ç®å½ç»æ
my-golang-atom/
âââ task.json
âââ go.mod
âââ go.sum
âââ main.go
3.4.2 task.json
{
"atomCode": "myGolangAtom",
"execution": {
"language": "golang",
"demands": [],
"target": "./app"
},
"input": {
"greeting": {
"label": "欢è¿è¯",
"type": "vuex-input",
"default": "Hello",
"required": true
},
"userName": {
"label": "ç¨æ·å",
"type": "vuex-input",
"required": true
}
},
"output": {
"result": {
"type": "string",
"description": "è¾åºç»æ"
}
}
}
3.4.3 go.mod
module xxx/bkdevops/myGolangAtom
go 1.14
require xxx/bkdevops/golang-atom-sdk v1.1.9
3.4.4 main.go
package main
import (
"fmt"
sdk "xxx/bkdevops/golang-atom-sdk"
)
func main() {
// è·åè¾å
¥åæ°
input := sdk.GetInput()
greeting := input["greeting"]
userName := input["userName"]
fmt.Printf("è¾å
¥åæ°: greeting=%s, userName=%s\n", greeting, userName)
// ä¸å¡é»è¾
result := fmt.Sprintf("%s, %s!", greeting, userName)
// 设置è¾åº
output := sdk.Output{
Status: sdk.StatusSuccess,
Message: "æ§è¡æå",
Type: sdk.OutputTypeDefault,
Data: map[string]sdk.DataField{
"result": {
Type: "string",
Value: result,
},
},
}
sdk.SetOutput(output)
}
åãæä»¶è¾åºè§è
4.1 è¾åºæ°æ®ç»æ
{
"status": "success",
"message": "æ§è¡æå",
"errorType": 1,
"errorCode": 0,
"platformCode": "",
"platformErrorCode": 0,
"type": "default",
"data": {
"outputVar1": {
"type": "string",
"value": "è¾åºå¼"
},
"outputVar2": {
"type": "artifact",
"value": ["/path/to/file1", "/path/to/file2"],
"artifactoryType": "PIPELINE",
"path": "/test/"
},
"outputVar3": {
"type": "report",
"reportType": "INTERNAL",
"label": "æµè¯æ¥å",
"path": "/workspace/report",
"target": "index.html"
}
}
}
4.2 status ç¶æå¼
| å¼ | 说æ |
|---|---|
success |
æ§è¡æå |
failure |
æ§è¡å¤±è´¥ |
4.3 è¾åºç±»å详解
4.3.1 string ç±»å
{
"outputVar": {
"type": "string",
"value": "è¾åºå符串ï¼é¿åº¦ä¸è¶
è¿4KB"
}
}
4.3.2 artifact ç±»åï¼æä»¶å½æ¡£ï¼
{
"buildArtifact": {
"type": "artifact",
"value": ["/workspace/output/app.apk", "/workspace/output/app.ipa"],
"artifactoryType": "PIPELINE",
"path": "/release/"
}
}
| 屿§ | 说æ |
|---|---|
value |
æä»¶ç»å¯¹è·¯å¾æ°ç» |
artifactoryType |
PIPELINEï¼æµæ°´çº¿ä»åºï¼æ CUSTOM_DIRï¼èªå®ä¹ä»åºï¼ |
path |
èªå®ä¹ä»åºæ¶çç¸å¯¹è·¯å¾ |
4.3.3 report ç±»åï¼æ¥å彿¡£ï¼
{
"testReport": {
"type": "report",
"reportType": "INTERNAL",
"label": "åå
æµè¯æ¥å",
"path": "/workspace/test-report",
"target": "index.html"
}
}
| 屿§ | 说æ |
|---|---|
reportType |
INTERNALï¼å
ç½®æ¥åï¼æ THIRDPARTYï¼ç¬¬ä¸æ¹é¾æ¥ï¼ |
label |
æ¥åå«å |
path |
æ¥åç®å½ç»å¯¹è·¯å¾ |
target |
å ¥å£æä»¶ï¼ç¸å¯¹äº pathï¼ |
url |
ç¬¬ä¸æ¹æ¥å龿¥ï¼reportType=THIRDPARTY æ¶ï¼ |
äºãé误ç è§è
5.1 é误类åï¼errorTypeï¼
| å¼ | ç±»å | 说æ |
|---|---|---|
| 1 | USER | ç¨æ·é ç½®é误ï¼åæ°ä¸åæ³çï¼ |
| 2 | THIRD_PARTY | ç¬¬ä¸æ¹å¹³å°é误 |
| 3 | PLUGIN | æä»¶é»è¾é误ï¼é»è®¤ï¼ |
5.2 éç¨é误ç ï¼100 å¼å¤´ï¼
| é误ç | 说æ | message è§è |
|---|---|---|
| 100001 | è¾å ¥åæ°éæ³ | è¾å ¥åæ°[xxx]éæ³ï¼<å ·ä½è¦æ±> |
| 100002 | ç½ç»è¿æ¥è¶ æ¶ | æ¥å£[xxx]ï¼è¿æ¥è¶ æ¶ |
| 100003 | æä»¶å¼å¸¸ | æªç¥çæä»¶å¼å¸¸ï¼<æ¥éä¿¡æ¯> |
| 100004 | 缺å°å¿ è¦åæ° | 缺å°å¿ è¦åæ°xxx |
| 100400 | HTTP 400 | æ¥å£[xxx]ï¼è¿åç [400] |
| 100401 | HTTP 401 | æ¥å£[xxx]ï¼è¿åç [401] |
| 100403 | HTTP 403 | æ¥å£[xxx]ï¼è¿åç [403] |
| 100404 | HTTP 404 | æ¥å£[xxx]ï¼è¿åç [404] |
| 100500 | HTTP 500 | æ¥å£[xxx]ï¼è¿åç [500] |
| 100502 | HTTP 502 | æ¥å£[xxx]ï¼è¿åç [502] |
5.3 æä»¶èªå®ä¹é误ç
- ç»ä¸ä»¥ 8 å¼å¤´
- 卿件代ç åºä¸å¢å
error.jsonæä»¶å£°æï¼
[
{
"errorCode": 800001,
"errorMsgZhCn": "é
ç½®æä»¶ä¸åå¨",
"errorMsgEn": "Config file not found"
},
{
"errorCode": 800002,
"errorMsgZhCn": "ç¼è¯å¤±è´¥",
"errorMsgEn": "Build failed"
}
]
5.4 ç¬¬ä¸æ¹å¹³å°éè¯¯ä¸æ¥
å½ errorType=2 æ¶ï¼éè¦å¡«åï¼
{
"errorType": 2,
"errorCode": 106001,
"platformCode": "tgit",
"platformErrorCode": 500,
"message": "è°ç¨å·¥èæ¥å£å¤±è´¥ï¼/api/v4/projectsï¼è¿åç [500]"
}
已注åçç¬¬ä¸æ¹å¹³å°æ è¯:
| å¹³å° | æ è¯ | errorCode åç¼ |
|---|---|---|
| èç¾ | bkci | 101 |
| CodeCC | bkci_codecc | 102 |
| å¶ååº | bkci_repo | 103 |
| ç¼è¯å é | bkci_turbo | 104 |
| ä½ä¸å¹³å° | bk_job | 105 |
| å·¥è | tgit | 106 |
| TAPD | tapd | 107 |
| æºç | zhiyan | 108 |
| ä¸å½©ç³ | rainbow | 109 |
| è ¾è®¯äº COS | cloud_cos | 110 |
å ãæä»¶å叿µç¨
6.1 å叿µç¨å¾
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â æä»¶å叿µç¨ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â â
â ââââââââââââ ââââââââââââ ââââââââââââ ââââââââââââ â
â â æäº¤åå¸ â â⺠â ç³»ç»æå»º â ââº â æµè¯éªè¯ â â⺠â å®¡æ ¸åå¸ â â
â â â â â â â â â â
â â å¡«åä¿¡æ¯ â â èªå¨æå
â â åå»ºæµæ°´çº¿ â â 馿¬¡éå®¡æ ¸ â â
â â éæ©çæ¬ â â ä¸ä¼ å¶å â â éªè¯åè½ â â å级å
å®¡æ ¸ â â
â ââââââââââââ ââââââââââââ ââââââââââââ ââââââââââââ â
â â â â â â
â â¼ â¼ â¼ â¼ â
â COMMITTING BUILDING TESTING AUDITING â
â â â â
â â¼ â¼ â
â BUILD_FAIL AUDIT_REJECT â
â â â
â â¼ â
â RELEASED â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
6.2 åå¸ç±»å
| ç±»å | 说æ | çæ¬å·åå |
|---|---|---|
| æ°ä¸æ¶ | 馿¬¡åå¸ | 1.0.0 |
| éå ¼å®¹å¼å级 | è¾å ¥è¾åºä¸å ¼å®¹ | ä¸»çæ¬å· +1 |
| å ¼å®¹å¼åè½æ´æ° | æ°å¢åè½ï¼å ¼å®¹æ§ç | æ¬¡çæ¬å· +1 |
| å ¼å®¹å¼é®é¢ä¿®æ£ | Bug ä¿®å¤ | ä¿®æ£å· +1 |
| åå²å¤§çæ¬ Bug fix | ä¿®å¤åå²çæ¬ | ä¿®æ£å· +1 |
6.3 çæ¬å·è§è
éµå¾ª SemVer è§èï¼ä¸»çæ¬å·.æ¬¡çæ¬å·.ä¿®æ£å·
- ä¸»çæ¬å·ï¼ä¸å ¼å®¹ç API ä¿®æ¹
- æ¬¡çæ¬å·ï¼åä¸å ¼å®¹çåè½æ§æ°å¢
- ä¿®æ£å·ï¼åä¸å ¼å®¹çé®é¢ä¿®æ£
ä¸ãæ¬å°è°è¯æå
7.1 è°è¯åå¤
å¨ä»£ç åºæ ¹ç®å½åå»ºä»¥ä¸æä»¶ï¼ä¸è¦æäº¤å°ä»£ç åºï¼ï¼
7.1.1 input.json
{
"inputParam1": "æµè¯å¼1",
"inputParam2": "æµè¯å¼2"
}
7.1.2 .sdk.json
{
"buildType": "DOCKER",
"projectId": "test-project",
"agentId": "1",
"secretKey": "test-secret",
"gateway": "xxx.xxx.xxx.xxx",
"buildId": "test-build-id",
"vmSeqId": "1"
}
注æ: æ¬å°è°è¯æ¶ä¸è½è°ç¨èç¾åå°æå¡ï¼éè¦å¨æµæ°´çº¿ä¸æ§è¡æææéï¼
7.2 Python æä»¶è°è¯
# å®è£
SDK
pip install python-atom-sdk
# æå
æä»¶
python ./setup.py sdist
# å®è£
æä»¶
pip install dist/XXX.tar.gz
# å¨ input.json æå¨ç®å½æ§è¡å
¥å£å½ä»¤
demo
7.3 Java æä»¶è°è¯
# æå
mvn clean package
# è¿è¡
java -jar target/myJavaAtom-jar-with-dependencies.jar
7.4 NodeJS æä»¶è°è¯
# å®è£
ä¾èµ
npm install
# æå
rollup -c rollup.config.js
# è¿è¡ï¼éè¦å
卿 ¹ç®å½å建 mock ç®å½ï¼å° input.json æ¾å
¥ï¼
node dist/bundle.js
7.5 Golang æä»¶è°è¯
# è¿è¡
go run main.go
# ææå»ºåè¿è¡
go build -o app main.go
./app
å «ãæä½³å®è·µ
8.1 åæ°æ ¡éª
# Python 示ä¾
def validate_params(input_params):
required_fields = ["repositoryUrl", "branch"]
for field in required_fields:
if not input_params.get(field):
return False, f"缺å°å¿
è¦åæ°: {field}"
return True, ""
8.2 é误å¤ç
// Java 示ä¾
try {
// ä¸å¡é»è¾
} catch (IOException e) {
result.setErrorInfo(
Status.failure,
100002, // ç½ç»é误
ErrorType.THIRD_PARTY,
new String[]{"æ¥å£è°ç¨å¤±è´¥: " + e.getMessage()}
);
}
8.3 æ¥å¿è¾åº
# Python ç¤ºä¾ - ä½¿ç¨æ¥å¿åç»
sdk.log.info("å¼å§æ§è¡ä»»å¡")
sdk.log.group_start("ç¼è¯é¶æ®µ")
sdk.log.info("æ£å¨ç¼è¯...")
sdk.log.group_end("ç¼è¯é¶æ®µ")
8.4 ææä¿¡æ¯å¤ç
- å¨
task.jsonä¸å°ææå段设置isSensitive: true - ææä¿¡æ¯ä¸ä¼å¨æ¥å¿ä¸æææ¾ç¤º
- ä½¿ç¨æä»¶ç§æè®¾ç½®ç®¡çè´¦å·å¯ç çæææ°æ®
ä¹ã常è§é®é¢
Q: task.json ä¿®æ¹åæµæ°´çº¿æ²¡æçæï¼ A: éè¦éæ°æå»ºæä»¶ï¼å¹¶å·æ°æµæ°´çº¿é¡µé¢æ¸ é¤ç¼åã
Q: å¦ä½è·åä¸ä¸ä¸ªæä»¶çè¾åºåéï¼ A: å¨åæ°ç±»ä¸å®ä¹åååæ°å³å¯èªå¨æ¥æ¶ã
Q: æä»¶æ§è¡æ¥é “Plugin File Sha1 is wrong!”ï¼ A: èç³»æä»¶ä½è éæ°åå¸æä»¶çæ¬ã
Q: å¦ä½è®©æä»¶æ¯æå¤æä½ç³»ç»ï¼
A: å¨ execution.os ä¸é
ç½®ä¸åæä½ç³»ç»çæ§è¡å½ä»¤ã
Q: æä»¶è¾åºåéé¿åº¦éå¶ï¼ A: string ç±»åè¾åºä¸è½è¶ è¿ 4KBã
çæ¬: 1.0.0 | æ´æ°æ¥æ: 2025-12-26