diff --git a/.github/workflows/jenkins.yml b/.github/workflows/jenkins.yml new file mode 100644 index 0000000..c834ac0 --- /dev/null +++ b/.github/workflows/jenkins.yml @@ -0,0 +1,24 @@ +name: 'Mayhem for API on Jenkins' +on: + workflow_dispatch: + +jobs: + jenkins-container-pipeline: + runs-on: ubuntu-22.04 + container: + image: ghcr.io/jenkinsci/jenkinsfile-runner:master + + steps: + - name: 'Checkout' + uses: actions/checkout@v1 + - name: 'Run Jenkins job' + uses: + jenkinsci/jfr-container-action@master + with: + command: run + jenkinsfile: jenkins/Jenkinsfile + pluginstxt: jenkins/plugins.txt + env: + MAYHEM_URL: 'https://app.mayhem.security' + MAYHEM_TOKEN: ${{ secrets.MAYHEM_TOKEN }} + diff --git a/README.md b/README.md index 61b111b..c61279e 100644 --- a/README.md +++ b/README.md @@ -117,3 +117,9 @@ If your API server sends back stacktraces in the 500 Internal Server Error (only do this in a test environment -- never in production!), Mayhem for API will try to map issues it finds to the exact line of code that triggered the issue. + +## Example runs + +- Github: see [this repo.](https://github.com/ForAllSecure/mapi-action-examples/actions/workflows/mapi.yml) +- Gitlab: see [https://gitlab.com/mayhem-forallsecure/mayhem-demo/-/jobs/10201916810](https://gitlab.com/mayhem-forallsecure/mayhem-demo/-/jobs/10201916810) +- Jenkins: copy the existing [Jenkinsfile](https://github.com/ForAllSecure/mapi-action-examples/blob/jenkins-example/jenkins/Jenkinsfile) into a new pipeline configuration and run the pipeline. Make sure to install the [plugins](https://github.com/ForAllSecure/mapi-action-examples/blob/jenkins-example/jenkins/plugins.txt) diff --git a/Jenkinsfile b/jenkins/Jenkinsfile similarity index 80% rename from Jenkinsfile rename to jenkins/Jenkinsfile index d93770a..8969445 100644 --- a/Jenkinsfile +++ b/jenkins/Jenkinsfile @@ -1,12 +1,19 @@ // First job pipeline { - agent any + agent { + docker { image 'python:3.9' } + } + + environment { + MAYHEM_URL = 'https://app.mayhem.security' + } stages { stage('Build') { steps { echo 'Building..' sh ''' + cd /workspace pip install -r requirements.txt ''' } @@ -15,6 +22,7 @@ pipeline { steps { echo 'Building..' sh ''' + cd /workspace FASTAPI_ENV=test python3 -m coverage run -m uvicorn src.main:app & ''' } @@ -27,9 +35,9 @@ pipeline { sh ''' curl -Lo mapi ${MAYHEM_URL}/cli/mapi/linux-musl/latest/mapi && chmod +x mapi ''' - withCredentials([string(credentialsId: 'MAPI_TOKEN', variable: 'MAPI_TOKEN')]) { + withCredentials([string(credentialsId: 'MAYHEM_TOKEN', variable: 'MAYHEM_TOKEN')]) { sh ''' - ./mapi login ${MAPI_TOKEN} + ./mapi login ${MAYHEM_TOKEN} ./mapi run forallsecure-demo/mapi-action-examples/fastapi auto "http://localhost:8000/openapi.json" --url "http://localhost:8000/" --junit junit.xml --sarif mapi.sarif --html mapi.html ''' } @@ -38,7 +46,7 @@ pipeline { sh 'pgrep python3 | xargs kill || true' /* Generate coverage report */ - sh 'python3 -m coverage xml -o coverage.xml' + sh 'python3 -m coverage xml -o coverage.xml || true' } } } @@ -54,7 +62,8 @@ pipeline { junit 'junit.xml' recordIssues(enabledForFailure: true, tool: sarif(pattern: 'mapi.sarif')) - cobertura coberturaReportFile: 'coverage.xml', onlyStable: 'false' + recordCoverage(tools: [[parser: 'COBERTURA', pattern: 'coverage.xml']], + sourceCodeRetention: 'LAST_BUILD') } } } diff --git a/jenkins/plugins.txt b/jenkins/plugins.txt new file mode 100644 index 0000000..b548a79 --- /dev/null +++ b/jenkins/plugins.txt @@ -0,0 +1,7 @@ +git +docker +docker-pipeline +warnings +junit +coverage +credentials \ No newline at end of file