如何在 GitHub Actions 中重用 Jenkins 的脚本

问题描述 投票:0回答:1

我正在将代码从 Jenkins 迁移到 GitHub Actions。我在 Jenkins 中的代码已经投入生产。

我的管道有什么作用?

  1. 读取 GitHub 上的

    Config.json
    文件。

  2. 在脚本中,它根据

    Config.json
    中的值初始化所有变量、数组、对象。

  3. 根据条件触发一系列 cURL 命令。

我打算做什么?

我不想为 GitHub Actions 重新发明轮子,而是想通过执行

script {}
中的
script.groovy
来重用 GitHub Actions 中 Jenkins 的
migrateToGitHubActions.yaml
代码。

script.groovy
具有来自 Jenkins 管道的
script {}
的确切代码。

来自我的詹金斯:

    pipeline{
    agent any
    
    stages{
        stage('Start'){
            steps{
                sh 'ls'
            }
        }
        stage('Clone Repo'){
            steps{
                git credentialsId: 'githubapp', url: 'https://github.com/configurations.git', branch: "${env}"
            }
        }
        stage('Configure'){
            steps{
                script{
                    sh 'cat Config.json'
                    def configs = readJSON(file: 'Config.json')
                    def totalBundles = configs.bundles.size()
                    println "Total Array Size =" + totalBundles
                    def productName = new Object[totalBundles]
                    ....
                }
            }
        }
    }
}

配置.json:

    {
    "bundles":
    [
        {
            "product":{
                "name" : "Product1",
                "proxies" : ["'Proxy1', 'Proxy2'"],
                "attributes" : [{"name":"Test1","value":"abc"}]
            },
            "app":{
                "name":"App1",
                "attributes": [{"name": "attribute1","value": "null"}],
                "developer": "[email protected]"
            }
        },
        {
            "product":{
                "name" : "Product2",
                "proxies" : ["'Proxy1', 'Proxy2'"],
                "attributes" : [{"name":"Test2","value":"xyz"}]
            },
            "app":{
                "name":"App1",
                "attributes": [{"name": "attribute2","value": "null"}],
                "developer": "[email protected]"
            }
        }
    ]
}

我的 GitHub Actions migrateToGitHubActions.yaml:

name: Config

on:
    workflow_dispatch:

jobs:
  build:
    runs-on: [abc]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: List files (Start)
        run: |
            ls

      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'adopt'
      - name: Install Groovy
        run: sudo apt-get update && sudo apt-get install -y groovy
      - name: Run Groovy script
        run: groovy script.groovy

script.groovy:

#!/usr/bin/env groovy

import groovy.json.JsonSlurper

println "*** Before Read ***"

// Reading JSON from file
def jsonFile = new File('AppsProductsConfig.json')
def configs = new JsonSlurper().parseText(jsonFile.text)

println "configs = $configs"
println "*** After Read ***"

def totalBundles = configs.bundles.size()
println "Total Array Size = $totalBundles"

// Initialization of arrays
def productName = new String[totalBundles]
def developer = new String[totalBundles]
def firstName = new String[totalBundles]
def lastName = new String[totalBundles]
def userName = new String[totalBundles]
def approvalType = new String[totalBundles]
def productAttributeName = new String[totalBundles]
def productAttributeValue = new String[totalBundles]
def displayName = new String[totalBundles]
def environments = new String[totalBundles]
def proxies = new Object[totalBundles][]
def appName = new String[totalBundles]
def appAttributeName = new String[totalBundles]
def appAttributeValue = new String[totalBundles]
def host = "example.com"
def USER = System.getenv('USER')

println "*** After Initialisation Read ***"

// Extract and Store Values
println "**** Read Variables ***"
for (int i = 0; i < totalBundles; i++) {
    def bundle = configs.bundles[i]

    // Products
    productName[i] = bundle.product.name
    approvalType[i] = "auto"
    productAttributeName[i] = bundle.product.attributes[0].name
    productAttributeValue[i] = bundle.product.attributes[0].value
    displayName[i] = bundle.product.name
    environments[i] = System.getenv('env') // Assuming 'env' is an environment variable
    proxies[i] = bundle.product.proxies

    // Developer
    developer[i] = bundle.app.developer
    firstName[i] = developer[i].takeWhile { it != '.' }
    def start = developer[i].indexOf(".") + 1
    def end = developer[i].indexOf("@")
    lastName[i] = developer[i].substring(start, end).replaceAll(/[^a-zA-Z]/, "")
    userName[i] = developer[i].takeWhile { it != '@' }

    // Apps
    appName[i] = bundle.app.name
    appAttributeName[i] = bundle.app.attributes[0].name
    appAttributeValue[i] = bundle.app.attributes[0].value

    println "*** Print Apps & Products ***"
    println "Product Name = $productName[i]"
    println "App Name = $appName[i]"
    println "Approval Type = $approvalType[i]"
    println "Product Attributes Name = $productAttributeName[i]"
    println "Product Attributes Value = $productAttributeValue[i]"
    println "Display Name = $displayName[i]"
    println "Environments = $environments[i]"
    println "Proxies = ${proxies[i]}"
    println "Developer = $developer[i]"
    println "App Attributes Name = $appAttributeName[i]"
    println "App Attributes Value = $appAttributeValue[i]"
}

for (int i = 0; i < totalBundles; i++) {
    def productBody = """{
        "approvalType": "${approvalType[i]}",
        "attributes": [{"name": "${productAttributeName[i]}", "value": "${productAttributeValue[i]}"}],
        "displayName": "${displayName[i]}",
        "environments": ["${environments[i]}"],
        "name": "${productName[i]}",
        "proxies": ${proxies[i]}
    }"""
    println "Product Body = $productBody"

    def developerBody = """{
        "email": "${developer[i]}",
        "firstName": "${firstName[i]}",
        "lastName": "${lastName[i]}",
        "userName": "${userName[i]}"
    }"""
    println "Developer Body = $developerBody"

    def appBody = """{
        "name": "${appName[i]}",
        "apiProducts": ["${productName[i]}"],
        "attributes": [{"name": "${appAttributeName[i]}", "value": "${appAttributeValue[i]}"}],
        "keyExpiresIn": "31536000000"
    }"""
    println "App Body = $appBody"

    // Products
    def createProductResponse = sh(script: "curl -k -s -w '\\n%{response_code}' --header 'Authorization:Basic $USER' --header 'Content-Type: application/json' --data-binary '$productBody' --request POST https://${host}/apiproducts", returnStdout: true).trim()
    println "$createProductResponse"

    if (createProductResponse.contains('201')) {
        println "*** Product ${productName[i]} created successfully ***"
    } else if (createProductResponse.contains('409')) {
        def updateProductResponse = sh(script: "curl -k -s -w '\\n%{response_code}' --header 'Authorization:Basic $USER' --header 'Content-Type: application/json' --data-binary '$productBody' --request PUT https://${host}/apiproducts/${productName[i]}", returnStdout: true).trim()
        println "$updateProductResponse"
        if (updateProductResponse.contains('200')) {
            println "*** Product ${productName[i]} updated successfully ***"
        } else {
            error "Failed to update ${productName[i]} with $updateProductResponse"
        }
    } else {
        error "Failed to create ${productName[i]} with $createProductResponse"
    }

    // Developers
    def createDeveloperResponse = sh(script: "curl -k -s -w '\\n%{response_code}' --header 'Authorization:Basic $USER' --header 'Content-Type: application/json' --data-binary '$developerBody' --request POST https://${host}/developers", returnStdout: true).trim()
    println "$createDeveloperResponse"

    if (createDeveloperResponse.contains('201')) {
        println "*** Developer ${developer[i]} created successfully ***"
    } else if (createDeveloperResponse.contains('409')) {
        println "*** Developer already exists: $createDeveloperResponse ***"
    } else {
        error "Failed to create ${developer[i]} with $createDeveloperResponse"
    }

    // Apps
    def createAppResponse = sh(script: "curl -k -s -w '\\n%{response_code}' --header 'Authorization:Basic $USER' --header 'Content-Type: application/json' --data-binary '$appBody' --request POST https://${host}/developers/${developer[i]}/apps", returnStdout: true).trim()
    println "$createAppResponse"

    if (createAppResponse.contains('201')) {
        println "*** App ${appName[i]} created successfully ***"
    } else if (createAppResponse.contains('409')) {
        def updateAppBody = """{
            "attributes": [{"name": "${appAttributeName[i]}", "value": "${appAttributeValue[i]}"}]
        }"""
        println "Updated App Body = $updateAppBody"

        def updateAppResponse = sh(script: "curl -k -s -w '\\n%{response_code}' --header 'Authorization:Basic $USER' --header 'Content-Type: application/json' --data-binary '$updateAppBody' --request PUT https://${host}/developers/${developer[i]}/apps/${appName[i]}", returnStdout: true).trim()
        println "$updateAppResponse"
        if (updateAppResponse.contains('200')) {
            println "*** App ${appName[i]} updated successfully ***"
        } else {
            error "Failed to update ${appName[i]} with $updateAppResponse"
        }
    } else {
        error "Failed to create ${appName[i]} with $createAppResponse"
    }
}

文件夹结构:

enter image description here

运行 migrateToGitHubActions.yaml 时,大多数行都遇到错误

GitHub Actions 的脚本编写能力比 Jenkins 少吗? Actions 中需要什么样的脚本?

错误:

警告:发生了非法反射访问操作警告: 非法反射访问 org.codehaus.groovy.reflection.CachedClass (文件:/usr/share/groovy/lib/groovy-2.4.17.jar)到方法 java.lang.Object.finalize() 警告:请考虑将此报告给 org.codehaus.groovy.reflection.CachedClass 的维护者警告: 使用 --illegal-access=warn 启用进一步非法的警告 反射访问操作警告:所有非法访问操作 将在未来版本中被拒绝 捕获: groovy.lang.MissingPropertyException:没有这样的属性:json for 类:java.io.File groovy.lang.MissingPropertyException:没有这样的 属性:类的 json:java.io.File at script.run(script.groovy:3) 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(本机 方法)在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 错误:进程已完成,退出代码为 1。

github jenkins-pipeline github-actions
1个回答
0
投票

我已经测试了您的工作流程配置,您面临的问题似乎与 groovy 脚本有关。

经过一些研究(以及 Chat GPT 使用),我发现您在 Jenkins 中使用的一些命令行无法直接在 Github Actions 上使用。

示例:

sh
命令仅在 Jenkins 上可用,您应该在 groovy 脚本中将此命令行替换为
execute
,然后在工作流中运行脚本时此操作应该起作用。

此外,我要求聊天 GPT 更正您共享的 groovy 脚本的第一个版本(我对 groovy 不熟悉),并通过使用此 工作流文件 让工作流程正常工作 here - 更新一些操作版本 - 以及这个更新的 Groovy 脚本


注意:如果您在 groovy 脚本方面遇到更多问题,我建议您在 StackOverflow 上使用

groovy
标签提出另一个问题,以便 groovy 社区给出更详细的答案。

© www.soinside.com 2019 - 2024. All rights reserved.