|
| 1 | +name: Semgrep SAST |
| 2 | +on: |
| 3 | + pull_request: |
| 4 | + branches: [main, master] |
| 5 | + schedule: |
| 6 | + - cron: '0 4 * * *' |
| 7 | + workflow_dispatch: |
| 8 | + inputs: |
| 9 | + reason: |
| 10 | + description: "Reason for manual run" |
| 11 | + required: false |
| 12 | + default: "Manual security scan" |
| 13 | + |
| 14 | +jobs: |
| 15 | + semgrep: |
| 16 | + name: Static analysis |
| 17 | + runs-on: ubuntu-latest |
| 18 | + container: |
| 19 | + image: semgrep/semgrep |
| 20 | + steps: |
| 21 | + - uses: actions/checkout@v4 |
| 22 | + |
| 23 | + - name: Run Semgrep |
| 24 | + run: | |
| 25 | + semgrep scan --config auto --error --json --output semgrep-results.json || true |
| 26 | + semgrep scan --config auto --error --sarif --output semgrep-results.sarif || true |
| 27 | +
|
| 28 | + # - name: Upload SARIF to GitHub |
| 29 | + # if: always() |
| 30 | + # uses: github/codeql-action/upload-sarif@v3 |
| 31 | + # with: |
| 32 | + # sarif_file: semgrep-results.sarif |
| 33 | + |
| 34 | + - name: Wrap results with repo metadata and send |
| 35 | + if: always() |
| 36 | + run: | |
| 37 | + # Build a wrapper with repo/org info + semgrep results |
| 38 | + # jq may not be in semgrep image, so use python which is guaranteed |
| 39 | + python3 -c " |
| 40 | + import json, os |
| 41 | +
|
| 42 | + # GitHub context |
| 43 | + repo_full = os.environ.get('GITHUB_REPOSITORY', 'unknown/unknown') # e.g. mapup/tollguru-api |
| 44 | + parts = repo_full.split('/', 1) |
| 45 | + org = parts[0] if len(parts) > 1 else 'unknown' |
| 46 | + repo = parts[1] if len(parts) > 1 else repo_full |
| 47 | +
|
| 48 | + ref = os.environ.get('GITHUB_REF', 'unknown') |
| 49 | + sha = os.environ.get('GITHUB_SHA', 'unknown') |
| 50 | + actor = os.environ.get('GITHUB_ACTOR', 'unknown') |
| 51 | + event = os.environ.get('GITHUB_EVENT_NAME', 'unknown') |
| 52 | + run_id = os.environ.get('GITHUB_RUN_ID', 'unknown') |
| 53 | + server = os.environ.get('GITHUB_SERVER_URL', 'https://github.com') |
| 54 | +
|
| 55 | + # Load semgrep results |
| 56 | + try: |
| 57 | + with open('semgrep-results.json', 'r') as f: |
| 58 | + semgrep = json.load(f) |
| 59 | + except Exception: |
| 60 | + semgrep = {'results': [], 'errors': [], 'version': 'unknown'} |
| 61 | +
|
| 62 | + # Wrap payload |
| 63 | + payload = { |
| 64 | + 'tool': 'semgrep', |
| 65 | + 'org': org, |
| 66 | + 'repo': repo, |
| 67 | + 'ref': ref, |
| 68 | + 'sha': sha, |
| 69 | + 'actor': actor, |
| 70 | + 'event': event, |
| 71 | + 'run_id': run_id, |
| 72 | + 'repo_url': f'{server}/{repo_full}', |
| 73 | + 'results': semgrep.get('results', []), |
| 74 | + 'errors': semgrep.get('errors', []), |
| 75 | + 'version': semgrep.get('version', 'unknown') |
| 76 | + } |
| 77 | +
|
| 78 | + with open('semgrep-payload.json', 'w') as f: |
| 79 | + json.dump(payload, f) |
| 80 | +
|
| 81 | + print(f'✅ Wrapped {len(payload[\"results\"])} findings for {org}/{repo}') |
| 82 | + " |
| 83 | +
|
| 84 | + curl -X POST "${{ secrets.SAST_WEBHOOK_URL }}?branch=${{ github.head_ref || github.ref_name }}&&repo=${{ github.event.repository.name }}" \ |
| 85 | + -H "Content-Type: application/json" \ |
| 86 | + -H "Authorization: Bearer ${{ secrets.SAST_WEBHOOK_TOKEN }}" \ |
| 87 | + -d @semgrep-payload.json |
| 88 | +
|
| 89 | +# name: Semgrep SAST |
| 90 | +# on: |
| 91 | +# pull_request: |
| 92 | +# branches: [main, master] |
| 93 | +# schedule: |
| 94 | +# - cron: '0 4 * * 1' |
| 95 | +# workflow_dispatch: # Enables manual run |
| 96 | +# inputs: |
| 97 | +# reason: |
| 98 | +# description: "Reason for manual run" |
| 99 | +# required: false |
| 100 | +# default: "Manual security scan" |
| 101 | + |
| 102 | +# jobs: |
| 103 | +# semgrep: |
| 104 | +# name: Static analysis |
| 105 | +# runs-on: ubuntu-latest |
| 106 | +# container: |
| 107 | +# image: semgrep/semgrep |
| 108 | +# steps: |
| 109 | +# - uses: actions/checkout@v4 |
| 110 | + |
| 111 | +# - name: Run Semgrep |
| 112 | +# run: | |
| 113 | +# semgrep scan --config auto --error --json --output semgrep-results.json || true |
| 114 | +# semgrep scan --config auto --error --sarif --output semgrep-results.sarif || true |
| 115 | + |
| 116 | +# # - name: Upload SARIF to GitHub |
| 117 | +# # if: always() |
| 118 | +# # uses: github/codeql-action/upload-sarif@v3 |
| 119 | +# # with: |
| 120 | +# # sarif_file: semgrep-results.sarif |
| 121 | + |
| 122 | +# - name: Send JSON to endpoint |
| 123 | +# if: always() |
| 124 | +# run: | |
| 125 | +# curl -X POST "${{ secrets.SAST_WEBHOOK_URL }}" \ |
| 126 | +# -H "Content-Type: application/json" \ |
| 127 | +# -H "Authorization: Bearer ${{ secrets.SAST_WEBHOOK_TOKEN }}" \ |
| 128 | +# -d @semgrep-results.json |
| 129 | + |
| 130 | +# # name: Semgrep SAST |
| 131 | +# # on: |
| 132 | +# # pull_request: |
| 133 | +# # branches: [main, master] |
| 134 | +# # schedule: |
| 135 | +# # - cron: '0 4 * * 1' |
| 136 | +# # workflow_dispatch: |
| 137 | + |
| 138 | +# # jobs: |
| 139 | +# # semgrep: |
| 140 | +# # name: Static analysis |
| 141 | +# # runs-on: ubuntu-latest |
| 142 | +# # container: |
| 143 | +# # image: semgrep/semgrep |
| 144 | +# # steps: |
| 145 | +# # - uses: actions/checkout@v4 |
| 146 | + |
| 147 | +# # - name: Run Semgrep |
| 148 | +# # run: semgrep scan --config auto --error --json --output semgrep-results.json || true |
| 149 | + |
| 150 | +# # - name: Send results to endpoint |
| 151 | +# # if: always() |
| 152 | +# # run: | |
| 153 | +# # curl -X POST "${{ secrets.SAST_WEBHOOK_URL }}" \ |
| 154 | +# # -H "Content-Type: application/json" \ |
| 155 | +# # -H "Authorization: Bearer ${{ secrets.SAST_WEBHOOK_TOKEN }}" \ |
| 156 | +# # -d @semgrep-results.json |
| 157 | + |
| 158 | +# # name: Semgrep SAST |
| 159 | +# # on: |
| 160 | +# # pull_request: |
| 161 | +# # branches: [main, master] |
| 162 | +# # schedule: |
| 163 | +# # - cron: '0 4 * * 1' # Weekly Monday 4am UTC |
| 164 | +# # workflow_dispatch: # Allow manual trigger |
| 165 | + |
| 166 | +# # jobs: |
| 167 | +# # semgrep: |
| 168 | +# # name: Static analysis |
| 169 | +# # runs-on: ubuntu-latest |
| 170 | +# # container: |
| 171 | +# # image: semgrep/semgrep |
| 172 | +# # steps: |
| 173 | +# # - uses: actions/checkout@v4 |
| 174 | +# # - run: semgrep scan --config auto --error --quiet |
0 commit comments