-
Notifications
You must be signed in to change notification settings - Fork 0
200 lines (181 loc) · 8.06 KB
/
Copy pathbuild-devcontainer.yml
File metadata and controls
200 lines (181 loc) · 8.06 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
196
197
198
199
200
name: Build and Publish Dev Container
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
inputs:
vscode_commit:
description: 'VS Code commit hash to use (defaults to Dockerfile declaration if not provided)'
required: false
type: string
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # For publishing container images
pull-requests: write # For PR comments from security scan
actions: write # For uploading artifacts from security scan
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Resolve VSCODE_COMMIT (input override > Dockerfile default)
id: vscode-commit
run: |
# If user provided an input, trust it. Otherwise parse Dockerfile ARG default.
if [ -n "${{ github.event.inputs.vscode_commit }}" ]; then
VSCODE_COMMIT="${{ github.event.inputs.vscode_commit }}"
SOURCE="workflow_input"
else
# Extract default from ARG line: ARG VSCODE_COMMIT=<hash>
VSCODE_COMMIT=$(grep -E '^ARG VSCODE_COMMIT=' Dockerfile | head -n1 | cut -d= -f2-)
if [ -z "$VSCODE_COMMIT" ]; then
echo "❌ Could not find default VSCODE_COMMIT in Dockerfile" >&2
exit 1
fi
SOURCE="dockerfile_default"
fi
# Basic validation (40 hex chars)
if ! echo "$VSCODE_COMMIT" | grep -Eq '^[0-9a-f]{40}$'; then
echo "❌ VSCODE_COMMIT '$VSCODE_COMMIT' is not a 40-char hex commit hash" >&2
exit 1
fi
VSCODE_SHORT=${VSCODE_COMMIT:0:7}
echo "Resolved VSCODE_COMMIT=$VSCODE_COMMIT (source=$SOURCE)"
echo "vscode_commit=$VSCODE_COMMIT" >> $GITHUB_OUTPUT
echo "vscode_short=$VSCODE_SHORT" >> $GITHUB_OUTPUT
echo "source=$SOURCE" >> $GITHUB_OUTPUT
echo "Short: $VSCODE_SHORT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=ref,event=tag
# Tags for default branch (main) only
type=sha,prefix={{branch}}-,enable={{is_default_branch}}
type=raw,value=latest,enable={{is_default_branch}}
type=raw,value=vscode-${{ steps.vscode-commit.outputs.vscode_short }},enable={{is_default_branch}}
type=raw,value=vscode-${{ steps.vscode-commit.outputs.vscode_short }}-{{sha}},enable={{is_default_branch}}
# Tags for PRs only
type=ref,prefix=pr-,suffix=-${{ steps.vscode-commit.outputs.vscode_short }},event=pr
type=ref,prefix=pr-,suffix=-${{ steps.vscode-commit.outputs.vscode_short }}-{{sha}},event=pr
- name: Extract tag names only
id: tags
run: |
# Extract just the tag portions (everything after the last colon)
TAGS=$(echo '${{ steps.meta.outputs.tags }}' | sed 's/.*://' | tr '\n' ',' | sed 's/,$//')
echo "tags=$TAGS" >> $GITHUB_OUTPUT
echo "Extracted tags: $TAGS"
# Free up disk space before security scan to prevent "no space left on device" errors
- name: Free Disk Space
run: |
echo "=== Disk space before cleanup ==="
df -h
echo "=== Removing unnecessary files ==="
sudo rm -rf /usr/share/dotnet
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/ghc
sudo rm -rf /opt/hostedtoolcache/CodeQL
sudo apt-get clean
echo "=== Disk space after cleanup ==="
df -h
- name: Build and publish dev container
uses: devcontainers/ci@v0.3
env:
VSCODE_COMMIT: ${{ steps.vscode-commit.outputs.vscode_commit }}
with:
imageName: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
imageTag: ${{ steps.tags.outputs.tags }}
cacheFrom: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
push: always
platform: linux/amd64
# Test the container with a simple validation
runCmd: |
echo "=== Testing dev container ==="
echo "Python: $(python3 --version)"
echo "Git: $(git --version)"
echo "Pip: $(pip3 --version)"
# Test Python import
python3 -c "import sys; print(f'Python executable: {sys.executable}')"
# Test if common development tools are available
if command -v zsh &> /dev/null; then
echo "Zsh: $(zsh --version)"
fi
if command -v quarto &> /dev/null; then
echo "Quarto: $(quarto --version)"
else
echo "Quarto: Not found (this may be expected)"
fi
echo "=== Dev container validation completed! ==="
# Using the custom Trivy Security Scan action from this repository
- name: Security Scan
id: security-scan
uses: smartdatafoundry/trivy-security-scan@v1.0.2
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
registry: ${{ env.REGISTRY }}
severity: 'CRITICAL,HIGH'
detailed-severity: 'CRITICAL,HIGH,MEDIUM,LOW'
ignore-unfixed: 'true'
exit-code: '0'
artifact-name: 'security-scan-results'
artifact-retention-days: '30'
github-token: ${{ secrets.GITHUB_TOKEN }}
post-pr-comment: 'true'
# Optional: Handle scan results programmatically
- name: Process scan results
run: |
echo "Security scan status: ${{ steps.security-scan.outputs.scan-status }}"
echo "Vulnerabilities found: ${{ steps.security-scan.outputs.vulnerability-count }}"
echo "Artifact ID: ${{ steps.security-scan.outputs.artifact-id }}"
# You can add custom logic here based on the scan results
if [ "${{ steps.security-scan.outputs.scan-status }}" = "vulnerabilities_found" ]; then
echo "⚠️ Security vulnerabilities detected!"
echo "Consider reviewing the security report before deploying."
# Optionally, you could fail the build for critical vulnerabilities:
# if [ "${{ steps.security-scan.outputs.vulnerability-count }}" -gt "10" ]; then
# echo "❌ Too many vulnerabilities found (> 10), failing build"
# exit 1
# fi
else
echo "✅ No critical or high severity vulnerabilities found!"
fi
- name: Container info
if: success()
run: |
echo "✅ Dev container built and published successfully!"
echo "📦 Registry: ${{ env.REGISTRY }}"
echo "🏷️ Image: ${{ env.IMAGE_NAME }}"
echo "🆔 Tags: ${{ steps.meta.outputs.tags }}"
echo "📝 Labels: ${{ steps.meta.outputs.labels }}"
echo "🔧 VSCode Commit: ${{ steps.vscode-commit.outputs.vscode_commit }}"
echo "📋 Short Commit: ${{ steps.vscode-commit.outputs.vscode_short }}"
echo "🗂️ Source: ${{ steps.vscode-commit.outputs.source }}"
echo ""
echo "To use this dev container:"
echo "1. Reference it in your devcontainer.json:"
echo ' "image": "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:<tag>"'
echo "2. Or use it directly with Docker:"
echo " docker run --rm -it ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:<tag>"
echo ""
echo "Available tags:"
echo "${{ steps.meta.outputs.tags }}" | tr ',' '\n' | sed 's/^/ - /'