Skip to content

Commit 26b7fda

Browse files
authored
Merge branch 'main' into dario.castane/ktlo/transitive-deps-generate
2 parents 824bb04 + 1e2f4d4 commit 26b7fda

24 files changed

Lines changed: 1183 additions & 216 deletions

File tree

.github/workflows/apps/govulncheck-fix.sh

Lines changed: 7 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -80,84 +80,13 @@ echo "==> Vulnerabilities with fixes:"
8080
cat "${FIXES_FILE}"
8181
echo ""
8282

83-
# ── Apply fixes ────────────────────────────────────────────────────────────────
84-
echo "==> Applying fixes..."
85-
while IFS=' ' read -r module fixed_version; do
86-
echo " Updating ${module}${fixed_version}"
87-
88-
# Update the module in every go.mod file that references it.
89-
while IFS= read -r gomod; do
90-
dir=$(dirname "${gomod}")
91-
echo "${dir}"
92-
go -C "${dir}" get "${module}@${fixed_version}" || {
93-
echo " ✗ Failed to update ${module} in ${dir}, skipping"
94-
}
95-
done < <(grep -rl "${module}" --include='go.mod' .)
96-
97-
done < "${FIXES_FILE}"
98-
99-
# ── Tidy all modified modules ─────────────────────────────────────────────────
100-
echo "==> Running go mod tidy..."
101-
while IFS= read -r gomod; do
102-
dir=$(dirname "${gomod}")
103-
go -C "${dir}" mod tidy || true
104-
done < <(find . -name go.mod \
105-
-not -path './.git/*' \
106-
-not -path './_tools/*' \
107-
-not -path './scripts/*')
108-
109-
# ── Check if anything changed ─────────────────────────────────────────────────
110-
if git diff --quiet; then
111-
echo "No changes after applying fixes (all dependencies already at required versions)."
112-
echo "has_fixes=false" >> "${GITHUB_OUTPUT}"
113-
rm -f "${FIXES_FILE}"
114-
exit 0
115-
fi
116-
117-
# ── Generate PR body ───────────────────────────────────────────────────────────
118-
{
119-
cat << 'HEADER'
120-
## Summary
121-
122-
This PR was automatically generated by the [Govulncheck Remediation](.github/workflows/govulncheck-fix.yml) workflow.
123-
124-
`govulncheck` identified the following reachable vulnerabilities with available fixes and updated the affected `go.mod` files.
125-
126-
> Unlike Dependabot, `govulncheck` uses call graph analysis to only report vulnerabilities in code paths that are **actually reachable** from this module, eliminating false positives from transitively-imported-but-never-called code.
127-
128-
### Updated Dependencies
129-
130-
HEADER
131-
132-
while IFS=' ' read -r module fixed_version; do
133-
echo "- \`${module}\`\`${fixed_version}\`"
134-
done < "${FIXES_FILE}"
135-
136-
cat << 'FOOTER'
137-
138-
## Test Plan
139-
140-
- [ ] CI passes with updated dependencies
141-
- [ ] `govulncheck-tests` job reports no remaining vulnerabilities for updated packages
142-
143-
## References
144-
145-
- [Filippo Valsorda: Turn Dependabot Off](https://words.filippo.io/dependabot/) — rationale for govulncheck over Dependabot alerts
146-
- [golang/govulncheck-action](https://github.com/golang/govulncheck-action) — official Go team action with SARIF support
147-
- [govulncheck documentation](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck) — JSON output format
148-
FOOTER
149-
} > /tmp/govulncheck-fix-body.md
150-
151-
# ── Generate commit message file (used by git commit -F) ─────────────────────
83+
echo "has_fixes=true" >> "${GITHUB_OUTPUT}"
15284
{
153-
echo "fix(deps): update dependencies with reachable vulnerabilities"
154-
echo ""
155-
echo "Updated by govulncheck remediation workflow."
156-
echo ""
157-
while IFS=' ' read -r module fixed_version; do
158-
echo "- ${module} -> ${fixed_version}"
159-
done < "${FIXES_FILE}"
160-
} > /tmp/govulncheck-fix-commit.txt
85+
echo "dependency_list<<EOF"
86+
cat "${FIXES_FILE}"
87+
echo "EOF"
88+
} >> "${GITHUB_OUTPUT}"
16189

162-
echo "has_fixes=true" >> "${GITHUB_OUTPUT}"
90+
out=$(awk 'NR>1{printf "\\n"} {printf "%s", $0}' "${FIXES_FILE}")
91+
echo "dependency_list=${out}" >> "${GITHUB_OUTPUT}"
16392
rm -f "${FIXES_FILE}"

.github/workflows/govulncheck-fix.yml

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ on:
77

88
permissions:
99
contents: write
10-
pull-requests: write
1110

1211
jobs:
1312
govulncheck-fix:
@@ -26,25 +25,45 @@ jobs:
2625
- name: Scan and fix vulnerabilities
2726
id: fix
2827
run: ./.github/workflows/apps/govulncheck-fix.sh
29-
- name: Configure git
30-
if: steps.fix.outputs.has_fixes == 'true'
31-
run: |
32-
git config user.name "github-actions[bot]"
33-
git config user.email "github-actions[bot]@users.noreply.github.com"
34-
gh auth setup-git
35-
env:
36-
GH_TOKEN: ${{ github.token }}
37-
- name: Create Pull Request
28+
- name: Notify Slack
3829
if: steps.fix.outputs.has_fixes == 'true'
30+
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
31+
with:
32+
webhook-type: incoming-webhook
33+
payload: |
34+
{
35+
"dependency_list": "${{ steps.fix.outputs.dependency_list }}",
36+
"text": "Found Vulnerabilities",
37+
"blocks": [
38+
{
39+
"type": "header",
40+
"text": {
41+
"type": "plain_text",
42+
"text": ":x: Found Vulnerabilities"
43+
}
44+
},
45+
{
46+
"type": "section",
47+
"fields": [
48+
{
49+
"type": "mrkdwn",
50+
"text": "*Repository:*\n${{ github.repository }}"
51+
},
52+
{
53+
"type": "mrkdwn",
54+
"text": "*Branch:*\n${{ github.ref_name }}"
55+
},
56+
{
57+
"type": "mrkdwn",
58+
"text": "*Workflow:*\n${{ github.workflow }}"
59+
},
60+
{
61+
"type": "mrkdwn",
62+
"text": "*Dependencies to upgrade:*\n${{ steps.fix.outputs.dependency_list }}"
63+
}
64+
]
65+
}
66+
]
67+
}
3968
env:
40-
GH_TOKEN: ${{ github.token }}
41-
run: |
42-
branch="automation/govulncheck-fix/${{ github.run_id }}"
43-
git checkout -b "${branch}"
44-
git add -- '**/go.mod' '**/go.sum'
45-
git commit -F /tmp/govulncheck-fix-commit.txt
46-
git push origin "${branch}"
47-
gh pr create \
48-
--title "fix(deps): update dependencies with reachable vulnerabilities" \
49-
--body-file /tmp/govulncheck-fix-body.md \
50-
--head="${branch}"
69+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_GOVULNCHECK_WEBHOOK_URL }}

.gitlab-ci.yml

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,36 @@ stages:
1111
- test-apps
1212

1313
variables:
14-
# This base image is created here: https://gitlab.ddbuild.io/DataDog/apm-reliability/benchmarking-platform/-/jobs/1422209418
15-
BASE_CI_IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/benchmarking-platform:dd-trace-go-96166511
14+
# This base image is created here: https://gitlab.ddbuild.io/DataDog/apm-reliability/benchmarking-platform/-/jobs/1577883208
15+
BASE_CI_IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/benchmarking-platform:dd-trace-go-106683130
1616
INDEX_FILE: index.txt
1717
BENCHMARK_TARGETS: "BenchmarkStartRequestSpan|BenchmarkHttpServeTrace|BenchmarkTracerAddSpans|BenchmarkStartSpan|BenchmarkSingleSpanRetention|BenchmarkOTelApiWithCustomTags|BenchmarkInjectW3C|BenchmarkExtractW3C|BenchmarkPartialFlushing|BenchmarkConfig|BenchmarkStartSpanConfig|BenchmarkGraphQL|BenchmarkSampleWAFContext|BenchmarkCaptureStackTrace|BenchmarkSetTagString|BenchmarkSetTagStringPtr|BenchmarkSetTagMetric|BenchmarkSetTagStringer|BenchmarkSerializeSpanLinksInMeta|BenchmarkLogs|BenchmarkParallelLogs|BenchmarkMetrics|BenchmarkParallelMetrics|BenchmarkPayloadVersions|BenchmarkOTLPTraceWriterAdd|BenchmarkOTLPTraceWriterFlush|BenchmarkOTLPProtoMarshal|BenchmarkOTLPProtoSize|BenchmarkOTLPTraceWriterConcurrent"
1818

1919
workflow:
2020
auto_cancel:
2121
on_new_commit: interruptible
2222

23+
.benchmark-rules: &benchmark-rules
24+
- if: '$CI_COMMIT_TAG =~ /^.*\/v\d+\.\d+\.\d+(?:-.*\.\d+)?$/'
25+
when: never
26+
- if: '$CI_COMMIT_BRANCH =~ /^graphite-base\/.*$/'
27+
when: never
28+
- if: '$CI_COMMIT_BRANCH =~ /^mq-working-branch-.*$/'
29+
when: never
30+
- if: '$CI_COMMIT_BRANCH == "main"'
31+
when: always
32+
interruptible: false
33+
- when: always
34+
interruptible: true
35+
2336
# In order to run benchmarks in parallel, we generate a matrix of test names based on the BENCHMARK_TARGETS variable.
2437
# This will be used in tandem with bp-runner in benchmarks.yml.
2538
# This will allow us to spin up a child job in GitLab CI that handles running all of the benchmarks in parallel.
2639
generate_matrix:
2740
stage: generate
2841
image: $BASE_CI_IMAGE
2942
tags: ["arch:amd64"]
30-
rules:
31-
# We don't want to run benchmarks when pushing release tags for nested modules
32-
- if: '$CI_COMMIT_TAG =~ /^.*\/v\d+\.\d+\.\d+(?:-.*\.\d+)?$/'
33-
when: never
34-
# We don't want to run benchmarks on graphite commits
35-
- if: '$CI_COMMIT_BRANCH =~ /^graphite-base\/.*$/'
36-
when: never
37-
# We don't want to run benchmarks on merge queue
38-
- if: '$CI_COMMIT_BRANCH =~ /^mq-working-branch-.*$/'
39-
when: never
40-
- if: '$CI_COMMIT_BRANCH == "main"'
41-
when: always
42-
interruptible: false
43-
- when: always
44-
interruptible: true
43+
rules: *benchmark-rules
4544
script: |
4645
echo "=== Debug: Environment ==="
4746
echo "Image: ${BASE_CI_IMAGE}"
@@ -65,13 +64,15 @@ trigger_child_pipeline:
6564
strategy: depend
6665
needs:
6766
- generate_matrix
67+
rules: *benchmark-rules
6868
variables:
6969
PARENT_PIPELINE_ID: $CI_PIPELINE_ID
7070

7171
check-big-regressions:
7272
stage: benchmarks
7373
needs:
7474
- job: trigger_child_pipeline
75+
rules: *benchmark-rules
7576
when: on_success
7677
tags:
7778
- "arch:amd64"
@@ -97,6 +98,7 @@ analyze-benchmark-results:
9798
stage: benchmarks
9899
needs:
99100
- job: trigger_child_pipeline
101+
rules: *benchmark-rules
100102
when: always
101103
tags:
102104
- "arch:amd64"

contrib/aws/aws-sdk-go-v2/internal/sns/sns.go

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ import (
2020
const (
2121
datadogKey = "_datadog"
2222
maxMessageAttributes = 10
23+
// maxMessageSizeBytes is the SNS maximum payload size for both Publish and
24+
// PublishBatch (262 144 bytes), minus a 256-byte safety margin for potential
25+
// undocumented framing overhead in SNS's internal size accounting.
26+
// https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html
27+
maxMessageSizeBytes = 262144 - 256
2328
)
2429

2530
var instr = internal.Instr
@@ -46,10 +51,15 @@ func handlePublish(span *tracer.Span, in middleware.InitializeInput) {
4651
return
4752
}
4853

54+
msgSize := publishInputSize(params)
55+
if msgSize+attributeSize(datadogKey, traceContext) > maxMessageSizeBytes {
56+
instr.Logger().Debug("Cannot inject trace context: message size limit would be exceeded")
57+
return
58+
}
59+
4960
if params.MessageAttributes == nil {
5061
params.MessageAttributes = make(map[string]types.MessageAttributeValue)
5162
}
52-
5363
injectTraceContext(traceContext, params.MessageAttributes)
5464
}
5565

@@ -66,11 +76,20 @@ func handlePublishBatch(span *tracer.Span, in middleware.InitializeInput) {
6676
return
6777
}
6878

79+
ctxSize := attributeSize(datadogKey, traceContext)
80+
runningSize := batchTotalSize(params.PublishBatchRequestEntries)
81+
6982
for i := range params.PublishBatchRequestEntries {
83+
if runningSize+ctxSize > maxMessageSizeBytes {
84+
instr.Logger().Debug("Cannot inject trace context: batch size limit would be exceeded")
85+
break
86+
}
7087
if params.PublishBatchRequestEntries[i].MessageAttributes == nil {
7188
params.PublishBatchRequestEntries[i].MessageAttributes = make(map[string]types.MessageAttributeValue)
7289
}
73-
injectTraceContext(traceContext, params.PublishBatchRequestEntries[i].MessageAttributes)
90+
if injectTraceContext(traceContext, params.PublishBatchRequestEntries[i].MessageAttributes) {
91+
runningSize += ctxSize
92+
}
7493
}
7594
}
7695

@@ -96,14 +115,54 @@ func getTraceContext(span *tracer.Span) (types.MessageAttributeValue, error) {
96115
return attribute, nil
97116
}
98117

99-
func injectTraceContext(traceContext types.MessageAttributeValue, messageAttributes map[string]types.MessageAttributeValue) {
100-
// SNS only allows a maximum of 10 message attributes.
118+
// attributeSize returns the byte size SNS counts for a single message attribute:
119+
// name + data type + value length.
120+
func attributeSize(name string, attr types.MessageAttributeValue) int {
121+
size := len(name)
122+
if attr.DataType != nil {
123+
size += len(*attr.DataType)
124+
}
125+
if attr.StringValue != nil {
126+
size += len(*attr.StringValue)
127+
}
128+
size += len(attr.BinaryValue)
129+
return size
130+
}
131+
132+
func sizeAttributes(attrs map[string]types.MessageAttributeValue) int {
133+
size := 0
134+
for name, attr := range attrs {
135+
size += attributeSize(name, attr)
136+
}
137+
return size
138+
}
139+
140+
func publishInputSize(params *sns.PublishInput) int {
141+
size := 0
142+
if params.Message != nil {
143+
size += len(*params.Message)
144+
}
145+
return size + sizeAttributes(params.MessageAttributes)
146+
}
147+
148+
func batchTotalSize(entries []types.PublishBatchRequestEntry) int {
149+
total := 0
150+
for _, entry := range entries {
151+
if entry.Message != nil {
152+
total += len(*entry.Message)
153+
}
154+
total += sizeAttributes(entry.MessageAttributes)
155+
}
156+
return total
157+
}
158+
159+
func injectTraceContext(traceContext types.MessageAttributeValue, messageAttributes map[string]types.MessageAttributeValue) bool {
101160
// https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html
102-
// Only inject if there's room.
103161
if len(messageAttributes) >= maxMessageAttributes {
104162
instr.Logger().Info("Cannot inject trace context: message already has maximum allowed attributes")
105-
return
163+
return false
106164
}
107165

108166
messageAttributes[datadogKey] = traceContext
167+
return true
109168
}

0 commit comments

Comments
 (0)