Ajout des résultats de test et génération de scripts au pipeline

Connectez votre flux de test et de construction existant au pipeline d'intégration continue en ajoutant les résultats de vos scripts de test et de construction, nouveaux ou existants, au flux d'intégration continue du pipeline DevSecOps.

Au début du pipeline, les scripts DevSecOps clonent automatiquement les dépôts d'application et de configuration dans les répertoires suivants :

  1. Le référentiel de l'application est cloné au chemin /workspace/app/<APP_REPO_NAME>

  2. Le référentiel de configuration du pipeline est cloné au chemin /workspace/app/one-pipeline-config-repo

À tout moment, si vous souhaitez exécuter des scripts situés dans ces dépôts, vous devez d'abord vous rendre dans les répertoires appropriés. Vous pouvez le faire en utilisant l'une des méthodes suivantes :

  1. Utiliser directement les chemins du dépôt cloné
  • Dépôt d'applications : cd "${WORKSPACE}/$APP_REPO_NAME"

  • Référentiel de configuration : cd "${WORKSPACE}/one-pipeline-config-repo/"

  1. Utilisation de la commande load_repo
  • Dépôt d'applications : cd "${WORKSPACE}/$(load_repo app-repo path)"

  • Référentiel de configuration : cd "${WORKSPACE}/$(load_repo one-pipeline-config-repo path)"

l'espace de travail fait référence au chemin racine /espace de travail/application.

Vous pouvez utiliser les étapes suivantes dans le pipeline d'intégration continue pour ajouter des étapes test et build :

  • Configuration
  • Test
  • Containerize (génération)
  • Préparer

Configuration du pipeline

Utilisez l'étape de configuration pour mettre en place votre environnement de test et de construction et introduire des informations dans le pipeline. Par exemple, vous pouvez utiliser plusieurs référentiels d'applications dans une seule génération. Vous pouvez cloner tous les dépôts dont vous avez besoin et faire en sorte que le pipeline soit informé de l'existence de ces dépôts lors des contrôles et des analyses liés à la conformité.

Le répertoire d'applications par défaut qui est cloné par le pipeline en interne et ajouté au pipeline en utilisant l'interface save_repo pipelinectl avec le nom de référence app-repo. Le référentiel par défaut est soit fourni par le paramètre d'interface utilisateur de pipeline de référentiel, soit sélectionné par son nom de liaison de chaîne d'outils, si vous configurez le pipeline à partir du modèle de chaîne d'outils.

Si vous souhaitez utiliser d'autres dépôts, clonez-les dans l'étape d' installation et utilisez la même interface save_repo pour les ajouter au pipeline.

Exemple

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

Ainsi, le reste du pipeline peut analyser ces référentiels à la recherche de violations de conformité et de vulnérabilités.

Les chemins enregistrés à l'aide de save_repo doivent être relatifs au chemin de l'espace de travail.

Vous n'avez pas besoin d'installer l'outil pipelinectl pour vos scripts ou images de base. Le pipeline de référence fournit les fichiers binaires pour le contexte de votre script.

Etape test

Cette étape consiste à exécuter des tests sur vos référentiels de code. Vous pouvez accéder aux dépôts ajoutés lors de l'étape d'installation en utilisant les interfaces list_repos et load_repo pipelinectl.

Exemple

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

Le contrôle de conformité du test unitaire est basé sur le code de sortie du script de scène. Si vos tests réussissent, quittez avec 0. Si ce n'est pas le cas, renvoyez un code de sortie différent de zéro à la fin.

Sauvegarde des résultats

Vos tests peuvent générer des rapports, tels que les résultats d'un test en JSON ou XML. Utilisez l'interface save_result pipelinectl dans cette étape pour associer les tests aux informations collectées de conformité créées en tant qu'artefacts d'informations collectées.

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

Le premier paramètre de save_results doit être le nom de l'étape de configuration de pipeline DevSecOps, par exemple, test, scan-artifact ou acceptance-test. Sinon, le collecteur de preuves ne pourra pas le trouver et l'attacher à l'élément de preuve approprié.

L'utilisation de l'interface pipelinectl de save_result garantit que le pipeline trouve vos artefacts de résultats, qu'ils sont téléchargés dans le casier de preuves et attachés aux preuves de conformité créées par le pipeline.

Exemple de preuve créée pour les tests d'unité lors de l'utilisation de 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"
    }
  ]
}

Etape build ou containerize

À ce stade, vous pouvez construire vos artefacts. Le pipeline fournit des fonctionnalités par défaut pour les artefacts de type image docker, mais vous pouvez construire n'importe quel artefact ici. Sauvegardez les artefacts créés pour le pipeline, afin qu'il puisse exécuter ultérieurement des examens dessus, ou utilisez les artefacts dans votre étape d'édition.

Pour fournir des informations sur vos artefacts de génération, utilisez l'interface pipelinectl save_artifact.

Exemple

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

Le format préféré pour le nom de l'image est image-URL:build-tag.

Si vous créez des images Docker, utilisez l'interface save_artifact pour envoyer ces images pour les tâches de signature d'image intégrée par défaut et de numérisation de l'appliance virtuelle CR IBM Informix.

Préparer

A la fin du pipeline, les artefacts de génération doivent être ajoutés à l'inventaire afin de pouvoir être promus vers l'environnement de déploiement. L'étape d'édition fournit une certaine souplesse si vous souhaitez ajouter d'autres artefacts à l'inventaire, par exemple, des chartes Helm.

Dans cette étape, vous pouvez utiliser la commande d'interface de ligne de commande cocoa inventory add et les données générées par les commandes pipelinectl, pour créer les entrées d'inventaire.

S'il y a des problèmes dans l'exécution du pipeline, vous pouvez choisir d'ignorer une mise à jour d'inventaire pour éviter un inventaire problématique. Pour ignorer la mise à jour de l'inventaire, utilisez les variables d'environnement suivantes:

  • skip-inventory-update-on-failure Variable d'environnement d'option d'adhésion du pipeline pour indiquer si le stock est mis à jour.
  • one-pipeline-status Définir sur 1, s'il y a un échec d'étape dans l'exécution du pipeline.

Vérifiez ces variables avant d'appeler cocoa inventory add dans cette étape.

Exemple

# 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

Pour utiliser l'interface de programmation, vous devez l'installer dans vos scripts ou utiliser une image de base dans laquelle l'interface de programmation est préinstallée.