Ir al contenido

Añadir el runner a tu pipeline de CI

El análisis se ejecuta en el pipeline de CI donde ya reside tu código - tu código fuente nunca sale de tu infraestructura. En los ejemplos siguientes, el runner se invoca con el token específico del proyecto.

Todos los ejemplos descargan la imagen del AppArch Hub; consulta esa página para la autenticación, la coincidencia de lenguaje y los errores comunes.

.github/workflows/apparch.yml
name: AppArch
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # the target branch is then in the clone: the change's own files and its merge base
- run: |
echo "$APPARCH_INSTALLATION_KEY" | docker login hub.apparch.io -u "$APPARCH_INSTALLATION_ID" --password-stdin
docker run --rm -v "$PWD:/workspace:ro" \
-e APPARCH_Collector__Token="$APPARCH_TOKEN" \
-e APPARCH_Collector__ApiUrl="https://api.yourdomain.com" \
-e GITHUB_EVENT_NAME -e GITHUB_REF -e GITHUB_REPOSITORY \
-e GITHUB_SERVER_URL -e GITHUB_BASE_REF -e GITHUB_SHA \
hub.apparch.io/collectors/dotnet:latest /workspace
env:
APPARCH_TOKEN: ${{ secrets.APPARCH_TOKEN }}
APPARCH_INSTALLATION_ID: ${{ secrets.APPARCH_INSTALLATION_ID }}
APPARCH_INSTALLATION_KEY: ${{ secrets.APPARCH_INSTALLATION_KEY }}
# Image pulls are authorized with your INSTALLATION credential, not the project token
# (Settings → CI/CD → Variables):
# DOCKER_AUTH_CONFIG = {"auths":{"hub.apparch.io":{"auth":"base64(<installation-id>:<installation-key>)"}}}
archpilot:
image: hub.apparch.io/collectors/dotnet:latest
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
variables:
APPARCH_Collector__Token: "$APPARCH_TOKEN"
APPARCH_Collector__ApiUrl: "https://api.yourdomain.com"
script:
# Optional flags: --modules archpilot,archscan (pin what runs)
# --fail-on critical (fail this step when findings at/above the level exist)
- apparch "$CI_PROJECT_DIR"
pipelines:
pull-requests:
'**':
- step:
image:
name: hub.apparch.io/collectors/dotnet:latest
username: $APPARCH_INSTALLATION_ID
password: $APPARCH_INSTALLATION_KEY
run-as-user: 0 # the clone belongs to root; a PR run fetches the target branch into it
script:
- export APPARCH_Collector__Token="$APPARCH_TOKEN"
- export APPARCH_Collector__ApiUrl="https://api.yourdomain.com"
- apparch "$BITBUCKET_CLONE_DIR"
trigger: none
pr: ['*']
pool: { vmImage: ubuntu-latest }
steps:
- checkout: self
fetchDepth: 0 # the target branch is then in the clone: the change's own files and its merge base
- script: |
echo "$(APPARCH_INSTALLATION_KEY)" | docker login hub.apparch.io -u "$(APPARCH_INSTALLATION_ID)" --password-stdin
docker run --rm -v "$(Build.SourcesDirectory):/workspace:ro" \
-e APPARCH_Collector__Token="$(APPARCH_TOKEN)" \
-e APPARCH_Collector__ApiUrl="https://api.yourdomain.com" \
-e SYSTEM_PULLREQUEST_PULLREQUESTID="$(System.PullRequest.PullRequestId)" \
-e SYSTEM_PULLREQUEST_TARGETBRANCH="$(System.PullRequest.TargetBranch)" \
-e SYSTEM_TEAMPROJECT="$(System.TeamProject)" \
-e BUILD_REPOSITORY_NAME="$(Build.Repository.Name)" \
-e SYSTEM_COLLECTIONURI="$(System.CollectionUri)" \
-e BUILD_SOURCEVERSION="$(Build.SourceVersion)" \
hub.apparch.io/collectors/dotnet:latest /workspace
pipeline {
agent { docker { image 'hub.apparch.io/collectors/dotnet:latest' registryUrl 'https://hub.apparch.io' registryCredentialsId 'apparch-hub' } }
environment {
APPARCH_Collector__Token = credentials('APPARCH_TOKEN')
APPARCH_Collector__ApiUrl = 'https://api.yourdomain.com'
// PR review (ArchPilot) needs the MR context set explicitly; without these the run is a full scan (ArchScan).
APPARCH_Collector__Provider__Type = 'gitlab' // gitlab | github | bitbucket | azuredevops
APPARCH_Collector__Provider__ProjectId = 'group/project'
APPARCH_Collector__Provider__PullRequestId = "${env.CHANGE_ID}"
}
stages {
stage('AppArch') {
steps {
sh 'apparch "$WORKSPACE"'
}
}
}
}

La próxima vez que se abra un PR/MR, ArchPilot dejará comentarios línea por línea. El runner elige el modo automáticamente: una pipeline de PR/MR ejecuta la revisión rápida (ArchPilot) y una pipeline de push ejecuta el análisis completo (ArchScan).

Las imágenes de los collectors se ejecutan con un usuario sin privilegios de root (uid 10001) y solo leen el checkout, aunque pertenezca a otro usuario. En una pull request el collector compara el cambio con su rama de destino (los archivos propios del cambio, su base de fusión); por eso esa rama debe estar en el clon:

  • GitHub Actions y Azure DevOps: los ejemplos obtienen todo el historial (fetch-depth: 0, fetchDepth: 0); la rama de destino ya está allí y no se escribe nada.
  • GitLab CI y Jenkins: funcionan tal cual (el clon de GitLab es escribible para el job, Jenkins ejecuta el contenedor con su propio usuario).
  • Bitbucket Pipelines: el clon siempre pertenece a root y el collector trae a él la rama de destino; por eso el ejemplo ejecuta el paso como root (run-as-user: 0).

Sin esto el paso sigue pasando, pero revisa todos los hallazgos en lugar de los del cambio y omite las comprobaciones que comparan con la rama de destino (una autorización eliminada, un nuevo ciclo de dependencias). Si su runner exige root en otro sitio, indíquelo explícitamente: docker run --user 0 ..., securityContext.runAsUser: 0 en Kubernetes.

Certificados autofirmados o de una CA interna

Sección titulada «Certificados autofirmados o de una CA interna»

Si tu instalación de AppArch se sirve con un certificado en el que el runner de CI no confía - una CA interna o un certificado autofirmado -, la ejecución falla al descargar el catálogo de reglas con un error TLS. Dos salidas, por orden de preferencia:

  1. Confiar en la CA dentro de la imagen del runner. El certificado se verifica como cualquier otro y no cambia nada en el collector.
  2. Desactivar la verificación con SslVerify:
Ventana de terminal
SslVerify=false # o SSL_VERIFY, o APPARCH_Collector__SslVerify

false, 0, no y off la desactivan; cualquier otro valor - incluido vacío - la deja activa. El collector .NET acepta además el flag --no-ssl-verify. Cada ejecución imprime ssl verify on o ssl verify OFF - server certificate not checked en su bloque de arranque.