Adición de los resultados de prueba y scripts de compilación al conducto

Conecte su flujo de pruebas y compilación existente a la canalización de integración continua añadiendo los resultados de sus scripts de pruebas y compilación nuevos o existentes al flujo de integración continua de la canalización DevSecOps.

Al inicio del proceso, los scripts de DevSecOps clonan automáticamente los repositorios de aplicaciones y configuración en los siguientes directorios:

  1. El repositorio de aplicaciones se clona en la ruta /workspace/app/<APP_REPO_NAME>

  2. El repositorio de configuración del oleoducto se clona en la ruta /workspace/app/one-pipeline-config-repo

En cualquier momento, si necesita ejecutar secuencias de comandos ubicadas en estos repositorios, primero debe navegar a los directorios correspondientes. Puede hacerlo utilizando uno de los siguientes métodos:

  1. Utilizar directamente las rutas de los repositorios clonados
  • Repositorio de aplicaciones: cd "${WORKSPACE}/$APP_REPO_NAME"

  • Configurar repositorio: cd "${WORKSPACE}/one-pipeline-config-repo/"

  1. Uso del comando load_repo
  • Repositorio de aplicaciones: cd "${WORKSPACE}/$(load_repo app-repo path)"

  • Configurar repositorio: cd "${WORKSPACE}/$(load_repo one-pipeline-config-repo path)"

$WORKSPACE se refiere a la ruta raíz /workspace/app.

Puede utilizar las siguientes etapas dentro de la interconexión de integración continua para añadir pasos de prueba y compilación:

  • Configuración
  • Test
  • Contenerizar (compilación)
  • Release

Configuración de conducto

Utilice la etapa de configuración para configurar su entorno de pruebas y de compilación e introducir información en la canalización. Por ejemplo, puede utilizar varios repositorios relacionados con app en una sola compilación. Puede clonar todos los repositorios que necesite y hacer que la canalización los tenga en cuenta en las comprobaciones y exploraciones relacionadas con el cumplimiento.

El repositorio de aplicaciones por defecto que es clonado por el pipeline internamente y añadido al pipeline utilizando la interfaz save_repo pipelinectl con el nombre de referencia app-repo. El valor predeterminado lo proporciona el parámetro de la interfaz de usuario de interconexión del repositorio o se selecciona por su nombre de enlace de la cadena de herramientas, si configura la interconexión a partir de la plantilla de la cadena de herramientas.

Si desea utilizar más repos, clónelos en la etapa de configuración y utilice la misma interfaz save_repo para añadirlos al pipeline.

Ejemplo

#
# 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}"

De esta forma, el resto de la interconexión puede explorar estos repositorios para detectar violaciones y vulnerabilidades de conformidad.

Las rutas que se guardan utilizando save_repo deben ser relativas a la ruta del espacio de trabajo.

No es necesario instalar la herramienta pipelinectl para los scripts o las imágenes base, la interconexión de referencia proporciona los binarios para el contexto del script.

Prueba

Esta etapa es donde se ejecutan las pruebas en los repositorios de código. Puede acceder a los repos añadidos en la fase de configuración a través de las interfaces list_repos y load_repo pipelinectl.

Ejemplo

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

El control de conformidad de la prueba unitaria se basa en el código de salida del script de la etapa. Si las pruebas pasan, salga con 0. Si no es así, devuelva un código de salida distinto de cero al final.

Cómo guardar los resultados

Sus pruebas pueden generar algunos artefactos de informe, como los resultados de una prueba en JSON o XML. Utilice la interfaz save_result pipelinectl en esta etapa para adjuntar las pruebas a las pruebas de conformidad creadas como artefactos de pruebas.

#
# 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

El primer parámetro de save_results debe ser el nombre de la etapa de configuración de interconexiones de DevSecOps, como test, scan-artifact o acceptance-test. De lo contrario, el encargado de la recogida de pruebas no podrá encontrarlo y adjuntarlo a la prueba adecuada.

El uso de la interfaz pipelinectl de save_result garantiza que la canalización encuentre sus artefactos de resultados, los cargue en el almacén de pruebas y los adjunte a las pruebas de conformidad creadas por la canalización.

Pruebas de ejemplo creadas para las pruebas de unidad mientras se utiliza 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"
    }
  ]
}

Creación o contenerización

En esta etapa, puedes construir tus artefactos. El pipeline proporciona algunas características por defecto para artefactos de tipo imagen docker, pero puedes construir cualquier artefacto aquí. Guarde los artefactos creados para el conducto, para que posteriormente pueda ejecutar exploraciones en él o utilizar los artefactos en la etapa de release.

Para proporcionar información sobre los artefactos creados, utilice la interfaz save_artifact de pipelinectl.

Ejemplo

#
# 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}"

El formato preferido para el nombre de la imagen es image-URL:build-tag.

Si crea imágenes Docker, utilice la interfaz save_artifact para enviar esas imágenes para las tareas de firma de imágenes incorporadas por defecto y de escaneado de CR IBM Informix Virtual Appliance.

Release

Al final de la interconexión, los artefactos creados se deben añadir al inventario, de modo que se puedan promocionar en el despliegue. La etapa de publicación proporciona flexibilidad si desea añadir otros artefactos al inventario como, por ejemplo, gráficos de Helm.

En esta etapa, puede utilizar el mandato de la CLI cocoa inventory add y los datos de los mandatos de pipelinectl para crear las entradas de inventario.

Si hay problemas en la ejecución del conducto, puede optar por omitir una actualización de inventario para evitar un inventario problemático. Para omitir la actualización de inventario, utilice las variables de entorno siguientes:

  • skip-inventory-update-on-failure Variable de entorno de participación de conducto para especificar si se actualiza el inventario.
  • one-pipeline-status Establecer en 1, si hay un error de etapa en la ejecución del conducto.

Compruebe estas variables antes de llamar a cocoa inventory add en esta etapa.

Ejemplo

# 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

Para utilizar la CLI, debe instalarla en sus scripts o utilizar una imagen base que tenga la CLI preinstalada.