將測試結果及建置 Script 新增至管線

透過將新的或現有的測試和建立腳本的結果加入 DevSecOps pipeline 持續整合流程,將您現有的測試和建立流程連接到持續整合管道。

在管道開始時,DevSecOps 腳本會自動將應用程式和組態套件庫複製到下列目錄中:

  1. 應用程式儲存庫複製於路徑 /workspace/app/<APP_REPO_NAME>

  2. 管道組態儲存庫克隆在路徑 /workspace/app/one-pipeline-config-repo

在任何階段,如果您需要執行這些套件庫中的指令碼,您必須先導航到適當的目錄。 您可以使用下列其中一種方法來執行:

  1. 直接使用複製的套件庫路徑
  • 應用程式儲存庫: cd "${WORKSPACE}/$APP_REPO_NAME"

  • 組態儲存庫: cd "${WORKSPACE}/one-pipeline-config-repo/"

  1. 使用 load_repo 指令
  • 應用程式儲存庫: cd "${WORKSPACE}/$(load_repo app-repo path)"

  • 組態儲存庫: cd "${WORKSPACE}/$(load_repo one-pipeline-config-repo path)"

$WORKSPACE 是指根目錄 /workspace/app。

您可以在連續整合管線內使用下列階段來新增測試及建置步驟:

  • 設定
  • 測試
  • Containerize (建置)
  • 版本

管線設定

使用 Setup 階段來設定測試及建置環境,並將資訊取回至管線。 例如,您可以在單一建置中使用多個應用程式相關的儲存庫。 您可以複製您需要的所有儲存庫,並讓管線瞭解相符性相關檢查及掃描中的那些儲存庫。

由管線在內部複製並使用 save_repo pipelinectl 介面與參照名稱 app-repo 新增至管線的預設應用程式儲存庫。 如果您從工具鏈範本設定管線,則預設儲存庫是由儲存庫管線使用者介面參數提供,或由其工具鏈連結名稱所選取。

如果您想要使用更多儲存庫,請在 setup 階段中複製它們,並使用相同的 save_repo 介面將它們新增至管線。

範例

#
# your scripts cloning the repositories
#
# make sure you prepare or export the following data from each cloned repository:
# - repository URL
# - path where it was cloned, relative to the $WORKSPACE path
# - cloned branch
# - latest commit hash
#
your_clone_scripts

#
# when cloning is complete
# use `save_repo` to add these information to the pipeline
# repo-reference-name can be any name, it is used to refer to the stored repo
#
save_repo <repo-reference-name> \
    url="${REPO_URL}" \
    path="${REPO_PATH}" \
    branch="${CLONED_BRANCH}" \
    commit="${LATEST_GIT_COMMIT}"

如此一來,管線的其餘部分可以掃描這些儲存庫,以找出相符性違規及漏洞。

使用 save_repo 儲存的路徑必須相對於工作區路徑。

您不需要為 Script 或基本映像檔安裝 pipelinectl 工具,參照管線會提供 Script 環境定義的二進位檔。

測試

此階段是您對程式碼儲存庫執行測試的位置。 您可以使用 list_reposload_repo pipelinectl 介面來存取在設定階段中新增的儲存庫。

範例

exit_code=0

#
# `list_repos` returns the list of the reference names of saved repos
#
list_repos | while IFS= read -r repository ; do

    #
    # load_repo returns a property of a saved repository
    #
    # Usage:
    # load_repo <repo-reference-name> <property>
    #
    url="$(load_repo "$repository" url)"
    sha="$(load_repo "$repository" commit)"
    branch="$(load_repo "$repository" branch)"
    path="$(load_repo "$repository" path)"

    #
    # use your repos to test, etc
    #
    run_tests
    result=$?

    if [ $result != 0 ]; then
        exit_code=$result
    fi
done

exit $exit_code

單元測試相符性控制基於暫置 Script 的結束碼。 如果測試通過,請結束 0。 如果沒有,則在結束時傳回非零結束碼。

儲存結果

您的測試可能會產生一些報告構件,例如 JSON 或 XML 中的測試結果。 在此階段中使用 save_result pipelinectl 介面,將測試附加至已建立的相符性證明作為證明構件。

#
# run tests with some test suite runner, and save output to results.json
#
test_runner -o results.json

#
# save the result for the pipeline, so it can attach it to the unit test evidence
#
save_result test results.json

save_results 的第一個參數必須是 DevSecOps 管道配置階段名稱,例如 test、scan-artifact 或 acceptance-test。 否則,證據收集者將無法找到它並將其附加至適當的證據。

使用 save_result pipelinectl 介面可確保管線找到您的結果構件,並將它們上傳至證明櫃,然後附加至管線所建立的相符性證明。

使用 save_result 時為單元測試建立的證明範例:

{
  "evidence_type_id": "com.ibm.unit_tests",
  "evidence_type_version": "1.0.0",
  "date": "2021-03-31T07:41:31.881Z",
  "result": "success",
  "pipeline_id": "8c2b6750-91db-45fb-98ee-51684843b821",
  "pipeline_run_id": "89a04de9-2795-4e8e-be90-52a92ac7f9c1",
  "issues": [],
  "artifacts": [
    {
      "url": "https://s3.us-south.cloud-object-storage.appdomain.cloud/cos-bucket-name/ci/89a04de9-2795-4e8e-be90-52a92ac7f9c1/artifacts/compliance-app-COMPACT-20210218231513608/unit-tests-results.json_d9619521e7444fef0ff052e59fd54049",
      "hash": "d9619521e7444fef0ff052e59fd54049"
    }
  ],
  "toolchain_crn": "crn:v1:bluemix:public:toolchain:us-south:a/40111714589c4f7099032529b26a7a63:39d4f080-55e5-42ee-a787-26d936fb2b97::",
  "log": [
    {
      "url": "https://cloud.ibm.com/devops/pipelines/tekton/8c2b6750-91db-45fb-98ee-51684843b821/runs/89a04de9-2795-4e8e-be90-52a92ac7f9c1/code-unit-tests/run-stage?env_id=ibm:yp:us-south",
      "hash": null
    },
    {
      "url": "https://s3.us-south.cloud-object-storage.appdomain.cloud/cos-bucket-name/ci/89a04de9-2795-4e8e-be90-52a92ac7f9c1/artifacts/logs/code-unit-tests/run-stage.log_dae902fb1455b1fc9c565273aa4fe1bc",
      "hash": "dae902fb1455b1fc9c565273aa4fe1bc"
    }
  ]
}

建置或儲存器化

在此階段中,您可以建置構件。 管線提供 Docker 映像檔類型構件的部分預設特性,但您可以在這裡建置任何構件。 儲存為管線建立的構件,以便稍後可以對它執行掃描,或使用發行階段中的構件。

若要提供建置構件的相關資訊,請使用 save_artifact pipelinectl 介面。

範例

#
# your scripts building the artifact
#
# make sure you prepare or export the following data from each built artifact:
# - type (image for docker images, package for rpms, npm tarballs, etc )
# - full artifact URL with version tag
# - artifact digest
#
your_build_scripts

#
# when the build is complete
# use `save_artifact` to add these information to the pipeline
# artifact-reference-name can be any name, it is used to refer to the stored artifact
#
save_artifact <artifact-reference-name> \
    type=image" \
    name="${IMAGE_URL}" \
    digest="${IMAGE_DIGEST}"

影像名稱的首選格式為 image-URL:build-tag

如果您建置 Docker 映像檔,請使用 save_artifact 介面來傳送那些映像檔,以進行預設內建映像檔簽署及 CR IBM Informix Virtual Appliance 掃描作業。

版本

在管線結束時,必須將建置的構件新增至庫存,以便將它們升級至部署。 如果您想要將其他構件新增至庫存,例如 Helm 圖表,則發行階段會提供彈性。

在此階段中,您可以使用 CLI cocoa inventory add 指令及 pipelinectl 指令中的資料,來建立庫存項目。

如果管線執行中有問題,您可以選擇跳過庫存更新,以避免有問題的庫存。 若要跳過庫存更新,請使用下列環境變數:

  • skip-inventory-update-on-failure 來自管線的接受環境變數,以指定是否更新庫存。
  • one-pipeline-status 如果管線執行中有階段失敗,請設為 1

在此階段中呼叫 cocoa inventory add 之前,請先檢查這些變數。

範例

# Check the status of pipeline and then release the artifacts to inventory

ONE_PIPELINE_STATUS=$(get_env one-pipeline-status 0)
if [ -n "$(get_env skip-inventory-update-on-failure "")" ]; then
    if [ $ONE_PIPELINE_STATUS -eq 1 ]; then
          echo "Skipping release stage as some of the pipeline stages are not successful."
          exit 1
    fi
fi

#
# `list_artifacts` returns the list of the reference names of saved artifacts
#
list_artifacts | while IFS= read -r artifact ; do
    #
    # Add a new value to the inventory repository. `cocoa inventory add` creates a new file with the name option,
    # if does not exist otherwise overwrites it.
    #
    cocoa inventory add \
        --name="${artifact}" \
        --artifact="$(load_artifact $artifact name)" \
        --repository-url="$(load_repo app-repo url)" \
        --commit-sha="$(load_repo app-repo commit)" \
        --build-number="${BUILD_NUMBER}" \
        --pipeline-run-id="${PIPELINE_RUN_ID}" \
        --version="$(get_env version)" \
        --app-artifacts="{ \
            \"signature\": \"$(load_artifact $artifact signature)\", \
            \"provenance\": \"$(load_artifact $artifact name)\"\
        }"
done

若要使用 CLI,您必須在 Script 中安裝它,或使用已預先安裝 CLI 的基本映像檔。