-
-
Notifications
You must be signed in to change notification settings - Fork 1
195 lines (176 loc) · 8.18 KB
/
Copy pathmcp-release.yml
File metadata and controls
195 lines (176 loc) · 8.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
name: "Publish MCP Server Image"
on:
workflow_dispatch:
push:
tags:
- 'v*'
env:
GHCR_REGISTRY: ghcr.io
DOCKERHUB_REGISTRY: docker.io
# Using 'cyberchef-mcp_v1' as requested for the package name
GHCR_IMAGE_NAME: ${{ github.repository_owner }}/cyberchef-mcp_v1
# Docker Hub image name (assumes username/repo format - update with your Docker Hub namespace)
# Example: if your Docker Hub username is 'myusername', this becomes 'myusername/cyberchef-mcp'
DOCKERHUB_IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/cyberchef-mcp
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
security-events: write
attestations: write # Required for attestation generation
id-token: write # Required for OIDC token generation (attestation signing)
steps:
- name: Configure git
run: git config --global init.defaultBranch master
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# =============================================================================
# Authentication: Log in to both GHCR and Docker Hub
# =============================================================================
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKERHUB_REGISTRY }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# =============================================================================
# Metadata Extraction: Generate tags and labels for both registries
# =============================================================================
- name: Extract metadata for GHCR
id: meta-ghcr
uses: docker/metadata-action@v5
with:
images: ${{ env.GHCR_REGISTRY }}/${{ env.GHCR_IMAGE_NAME }}
tags: |
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{version}}
type=sha
- name: Extract metadata for Docker Hub
id: meta-dockerhub
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKERHUB_REGISTRY }}/${{ env.DOCKERHUB_IMAGE_NAME }}
tags: |
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{version}}
type=sha
type=raw,value=latest,enable={{is_default_branch}}
# =============================================================================
# Build and Push: Single build, multi-registry push with attestations
# =============================================================================
# CRITICAL: Supply chain attestations for Docker Scout health score compliance
# Docker Hub health scores require BOTH provenance and SBOM attestations.
# These attestations account for 15 points out of 100 in the health score.
# Missing attestations can drop the score from A to C grade.
#
# Dual SBOM Strategy:
# 1. Docker attestation SBOM (below): Attached to image manifest for
# Docker Scout health scores, `docker sbom` command, and registry verification
# 2. Trivy SBOM artifact (separate step): Downloadable CycloneDX file
# for offline audits, compliance reports, and third-party tools
#
# References:
# - Docker Scout Policies: https://docs.docker.com/scout/policy/
# - Health Scores: https://docs.docker.com/scout/policy/scores/
# - GitHub Actions Attestations: https://docs.docker.com/build/ci/github-actions/attestations/
# =============================================================================
- name: Build and push Docker image to both registries
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.mcp
push: true
tags: |
${{ steps.meta-ghcr.outputs.tags }}
${{ steps.meta-dockerhub.outputs.tags }}
labels: ${{ steps.meta-ghcr.outputs.labels }}
platforms: linux/amd64
# Supply chain attestations (CRITICAL for Docker Hub health score)
provenance: mode=max # Max-level provenance for SLSA Build Level 3 compliance
sbom: true # Generate and attach SBOM attestation (in-toto SPDX format)
# Note: Attestations are automatically pushed with the image to both registries
# =============================================================================
# Export: Create tarball for offline distribution
# =============================================================================
# Note: We pull from Docker Hub since that's the primary distribution channel
- name: Pull Docker image from Docker Hub for export
run: |
docker pull "$DOCKERHUB_REGISTRY/$DOCKERHUB_IMAGE_NAME:latest"
- name: Export Docker image as tarball
env:
TAG_NAME: ${{ github.ref_name }}
run: |
docker save "$DOCKERHUB_REGISTRY/$DOCKERHUB_IMAGE_NAME:latest" | gzip > "cyberchef-mcp-${TAG_NAME}-docker-image.tar.gz"
ls -lh cyberchef-mcp-*.tar.gz
# =============================================================================
# Security: Generate SBOM and Vulnerability Scans
# =============================================================================
# Generate Software Bill of Materials (SBOM) - Part 2 of Dual Strategy
# This Trivy-generated SBOM complements the Docker attestation SBOM above
# Purpose: Provides CycloneDX format for:
# - Offline security audits (no registry access required)
# - Third-party SBOM analysis tools (Dependency-Track, Grype, etc.)
# - Compliance documentation (SOC 2, ISO 27001, NIST SSDF)
# - Manual verification and archival
- name: Generate SBOM with Trivy (CycloneDX artifact)
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: '${{ env.DOCKERHUB_REGISTRY }}/${{ env.DOCKERHUB_IMAGE_NAME }}:latest'
format: 'cyclonedx'
output: 'sbom.cyclonedx.json'
vuln-type: 'os,library'
# Security: Run vulnerability scan on release image (scanning Docker Hub image)
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: '${{ env.DOCKERHUB_REGISTRY }}/${{ env.DOCKERHUB_IMAGE_NAME }}:latest'
format: 'sarif'
output: 'trivy-release-results.sarif'
severity: 'CRITICAL,HIGH'
vuln-type: 'os,library'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: 'trivy-release-results.sarif'
category: 'trivy-release-scan'
# Create GitHub Release if it doesn't exist
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ github.ref_name }}
run: |
# Check if release exists, create if not
if ! gh release view "$TAG_NAME" &>/dev/null; then
echo "Creating release for $TAG_NAME"
gh release create "$TAG_NAME" \
--title "Release $TAG_NAME" \
--notes "See [CHANGELOG.md](CHANGELOG.md) for details." \
--verify-tag
else
echo "Release $TAG_NAME already exists"
fi
- name: Attach tarball to release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ github.ref_name }}
run: |
gh release upload "$TAG_NAME" "cyberchef-mcp-${TAG_NAME}-docker-image.tar.gz" --clobber
- name: Attach SBOM to release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ github.ref_name }}
run: |
gh release upload "$TAG_NAME" sbom.cyclonedx.json --clobber