Skip to content

Commit ee0f27f

Browse files
authored
Merge branch 'main' into experimental-go-idna-ip-literal-smuggle
2 parents a463f43 + 3a9633b commit ee0f27f

6,253 files changed

Lines changed: 284593 additions & 96926 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.bazelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ build --compilation_mode opt
1111
common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
1212

1313
build --repo_env=CC=clang --repo_env=CXX=clang++
14+
# The standalone Linux toolchain uses gold, which does not support the
15+
# LLD-specific -z nostart-stop-gc workaround enabled by rules_swift.
16+
build:linux --features=-swift.lld_gc_workaround
1417
# Disable Android SDK auto-detection (we don't use it, and rules_android has Bazel 9 compatibility issues)
1518
build --repo_env=ANDROID_HOME=
1619

.github/instructions/ql-files.instructions.md

Lines changed: 0 additions & 6 deletions
This file was deleted.

.github/workflows/check-change-note.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
name: Check change note
22

33
permissions:
4+
contents: read
45
pull-requests: read
56

67
on:
7-
pull_request_target:
8+
pull_request:
89
types: [labeled, unlabeled, opened, synchronize, reopened, ready_for_review]
910
paths:
1011
- "*/ql/src/**/*.ql"
@@ -23,7 +24,7 @@ jobs:
2324
env:
2425
REPO: ${{ github.repository }}
2526
PULL_REQUEST_NUMBER: ${{ github.event.number }}
26-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27+
GH_TOKEN: ${{ github.token }}
2728
runs-on: ubuntu-latest
2829
steps:
2930

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
name: Update Go version
2+
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: "0 3 * * 1" # Run weekly on Mondays at 3 AM UTC (1 = Monday)
7+
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
12+
jobs:
13+
update-go-version:
14+
name: Check and update Go version
15+
if: github.repository == 'github/codeql'
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v5
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Set up Git
25+
run: |
26+
git config user.name "github-actions[bot]"
27+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
28+
29+
- name: Fetch latest Go version
30+
id: fetch-version
31+
run: |
32+
LATEST_GO_VERSION=$(curl -s https://go.dev/dl/?mode=json | jq -r '.[0].version')
33+
34+
if [ -z "$LATEST_GO_VERSION" ] || [ "$LATEST_GO_VERSION" = "null" ]; then
35+
echo "Error: Failed to fetch latest Go version from go.dev"
36+
exit 1
37+
fi
38+
39+
echo "Latest Go version from go.dev: $LATEST_GO_VERSION"
40+
echo "version=$LATEST_GO_VERSION" >> $GITHUB_OUTPUT
41+
42+
# Extract version numbers (e.g., go1.26.0 -> 1.26.0)
43+
LATEST_VERSION_NUM=$(echo $LATEST_GO_VERSION | sed 's/^go//')
44+
echo "version_num=$LATEST_VERSION_NUM" >> $GITHUB_OUTPUT
45+
46+
# Extract major.minor version (e.g., 1.26.0 -> 1.26)
47+
LATEST_MAJOR_MINOR=$(echo $LATEST_VERSION_NUM | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
48+
echo "major_minor=$LATEST_MAJOR_MINOR" >> $GITHUB_OUTPUT
49+
50+
- name: Check current Go version
51+
id: current-version
52+
run: |
53+
CURRENT_VERSION=$(sed -n 's/.*go_sdk\.download(version = \"\([^\"]*\)\".*/\1/p' MODULE.bazel)
54+
55+
if [ -z "$CURRENT_VERSION" ]; then
56+
echo "Error: Could not extract Go version from MODULE.bazel"
57+
exit 1
58+
fi
59+
60+
echo "Current Go version in MODULE.bazel: $CURRENT_VERSION"
61+
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
62+
63+
# Extract major.minor version
64+
CURRENT_MAJOR_MINOR=$(echo $CURRENT_VERSION | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
65+
echo "major_minor=$CURRENT_MAJOR_MINOR" >> $GITHUB_OUTPUT
66+
67+
- name: Compare versions
68+
id: compare
69+
run: |
70+
LATEST="${{ steps.fetch-version.outputs.version_num }}"
71+
CURRENT="${{ steps.current-version.outputs.version }}"
72+
73+
echo "Latest: $LATEST"
74+
echo "Current: $CURRENT"
75+
76+
if [ "$LATEST" = "$CURRENT" ]; then
77+
echo "Go version is up to date"
78+
echo "needs_update=false" >> $GITHUB_OUTPUT
79+
else
80+
echo "Go version needs update from $CURRENT to $LATEST"
81+
echo "needs_update=true" >> $GITHUB_OUTPUT
82+
fi
83+
84+
- name: Update Go version in files
85+
if: steps.compare.outputs.needs_update == 'true'
86+
run: |
87+
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
88+
LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}"
89+
CURRENT_VERSION="${{ steps.current-version.outputs.version }}"
90+
CURRENT_MAJOR_MINOR="${{ steps.current-version.outputs.major_minor }}"
91+
92+
echo "Updating from $CURRENT_VERSION to $LATEST_VERSION_NUM"
93+
94+
# Escape dots in current version strings for use in sed patterns
95+
CURRENT_VERSION_ESCAPED=$(echo "$CURRENT_VERSION" | sed 's/\./\\./g')
96+
CURRENT_MAJOR_MINOR_ESCAPED=$(echo "$CURRENT_MAJOR_MINOR" | sed 's/\./\\./g')
97+
98+
# Update MODULE.bazel
99+
sed -i "s/go_sdk\.download(version = \"$CURRENT_VERSION_ESCAPED\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel
100+
if ! grep -q "go_sdk.download(version = \"$LATEST_VERSION_NUM\")" MODULE.bazel; then
101+
echo "Error: Failed to update MODULE.bazel"
102+
exit 1
103+
fi
104+
105+
# Update go/extractor/go.mod
106+
if ! sed -i "s/^go $CURRENT_MAJOR_MINOR_ESCAPED\$/go $LATEST_MAJOR_MINOR/" go/extractor/go.mod; then
107+
echo "Warning: Failed to update go directive in go.mod"
108+
fi
109+
if ! sed -i "s/^toolchain go$CURRENT_VERSION_ESCAPED\$/toolchain go$LATEST_VERSION_NUM/" go/extractor/go.mod; then
110+
echo "Warning: Failed to update toolchain in go.mod"
111+
fi
112+
113+
# Update go/extractor/autobuilder/build-environment.go
114+
if ! sed -i "s/var maxGoVersion = util\.NewSemVer(\"$CURRENT_MAJOR_MINOR_ESCAPED\")/var maxGoVersion = util.NewSemVer(\"$LATEST_MAJOR_MINOR\")/" go/extractor/autobuilder/build-environment.go; then
115+
echo "Warning: Failed to update build-environment.go"
116+
fi
117+
118+
# Update go/actions/test/action.yml
119+
if ! sed -i "s/default: \"~$CURRENT_VERSION_ESCAPED\"/default: \"~$LATEST_VERSION_NUM\"/" go/actions/test/action.yml; then
120+
echo "Warning: Failed to update action.yml"
121+
fi
122+
123+
# Show what changed
124+
git diff
125+
126+
- name: Check for changes
127+
id: check-changes
128+
if: steps.compare.outputs.needs_update == 'true'
129+
run: |
130+
if git diff --quiet; then
131+
echo "No changes detected"
132+
echo "has_changes=false" >> $GITHUB_OUTPUT
133+
else
134+
echo "Changes detected"
135+
echo "has_changes=true" >> $GITHUB_OUTPUT
136+
fi
137+
138+
- name: Check for existing PR
139+
if: steps.check-changes.outputs.has_changes == 'true'
140+
id: check-pr
141+
env:
142+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
143+
run: |
144+
BRANCH_NAME="workflow/go-version-update"
145+
PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number')
146+
147+
if [ -n "$PR_NUMBER" ]; then
148+
echo "Existing PR found: #$PR_NUMBER"
149+
echo "pr_exists=true" >> $GITHUB_OUTPUT
150+
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
151+
else
152+
echo "No existing PR found"
153+
echo "pr_exists=false" >> $GITHUB_OUTPUT
154+
fi
155+
156+
- name: Commit and push changes
157+
if: steps.check-changes.outputs.has_changes == 'true'
158+
run: |
159+
BRANCH_NAME="workflow/go-version-update"
160+
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
161+
LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}"
162+
163+
# Create or switch to branch
164+
git checkout -B "$BRANCH_NAME"
165+
166+
# Stage and commit changes
167+
git add MODULE.bazel go/extractor/go.mod go/extractor/autobuilder/build-environment.go go/actions/test/action.yml
168+
git commit -m "Go: Update to $LATEST_VERSION_NUM"
169+
170+
# Push changes
171+
git push --force-with-lease origin "$BRANCH_NAME"
172+
173+
- name: Create or update PR
174+
if: steps.check-changes.outputs.has_changes == 'true'
175+
env:
176+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
177+
run: |
178+
BRANCH_NAME="workflow/go-version-update"
179+
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
180+
CURRENT_VERSION="${{ steps.current-version.outputs.version }}"
181+
182+
PR_TITLE="Go: Update to $LATEST_VERSION_NUM"
183+
184+
PR_BODY=$(cat <<EOF
185+
This PR updates Go from $CURRENT_VERSION to $LATEST_VERSION_NUM.
186+
187+
Updated files:
188+
- \`MODULE.bazel\` - go_sdk.download version
189+
- \`go/extractor/go.mod\` - go directive and toolchain
190+
- \`go/extractor/autobuilder/build-environment.go\` - maxGoVersion (only if MAJOR.MINOR changes)
191+
- \`go/actions/test/action.yml\` - default go-test-version
192+
193+
This PR was automatically created by the [Go version update workflow](https://github.com/${{ github.repository }}/blob/main/.github/workflows/go-version-update.yml).
194+
EOF
195+
)
196+
197+
if [ "${{ steps.check-pr.outputs.pr_exists }}" = "true" ]; then
198+
echo "Updating existing PR #${{ steps.check-pr.outputs.pr_number }}"
199+
gh pr edit "${{ steps.check-pr.outputs.pr_number }}" --title "$PR_TITLE" --body "$PR_BODY"
200+
else
201+
echo "Creating new PR"
202+
gh pr create \
203+
--title "$PR_TITLE" \
204+
--body "$PR_BODY" \
205+
--base main \
206+
--head "$BRANCH_NAME" \
207+
--label "Go"
208+
fi

.github/workflows/labeler.yml

Lines changed: 136 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,144 @@
11
name: "Pull Request Labeler"
2+
23
on:
3-
- pull_request_target
4+
schedule:
5+
# Reconcile recently updated PRs promptly, including unapproved forks and
6+
# conflicted PRs for which pull_request workflows do not run.
7+
- cron: "7,22,37,52 * * * *"
8+
# Reconcile one stable shard of all open PRs each hour to recover from
9+
# delayed or missed scheduled runs.
10+
- cron: "12 * * * *"
11+
workflow_dispatch:
12+
inputs:
13+
pr_number:
14+
description: "Open pull request number to reconcile"
15+
required: true
16+
type: string
17+
18+
permissions: {}
419

5-
permissions:
6-
contents: read
7-
pull-requests: write
20+
concurrency:
21+
group: pull-request-labeler
22+
cancel-in-progress: false
823

924
jobs:
1025
triage:
26+
if: github.ref_name == github.event.repository.default_branch
1127
runs-on: ubuntu-latest
28+
timeout-minutes: 30
29+
permissions:
30+
contents: read
31+
pull-requests: write
1232
steps:
13-
- uses: actions/labeler@v4
14-
with:
15-
repo-token: "${{ secrets.GITHUB_TOKEN }}"
33+
- uses: actions/checkout@v5
34+
with:
35+
persist-credentials: false
36+
sparse-checkout: .github/labeler.yml
37+
sparse-checkout-cone-mode: false
38+
39+
- name: Collect pull requests to reconcile
40+
id: collect
41+
env:
42+
GH_TOKEN: ${{ github.token }}
43+
REPO: ${{ github.repository }}
44+
EVENT_NAME: ${{ github.event_name }}
45+
SCHEDULE: ${{ github.event.schedule }}
46+
REQUESTED_PR: ${{ inputs.pr_number }}
47+
run: |
48+
set -euo pipefail
49+
50+
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
51+
if [[ ! "$REQUESTED_PR" =~ ^[1-9][0-9]*$ ]]; then
52+
echo "Invalid pull request number: $REQUESTED_PR"
53+
exit 1
54+
fi
55+
56+
pr_json=$(gh api "repos/$REPO/pulls/$REQUESTED_PR")
57+
candidates=$(jq -c '[{
58+
number: .number,
59+
head_sha: .head.sha
60+
}]' <<<"$pr_json")
61+
else
62+
pulls_json=$(gh api --paginate \
63+
"repos/$REPO/pulls?state=open&sort=updated&direction=desc&per_page=100" |
64+
jq -cs 'add')
65+
66+
if [ "$SCHEDULE" = "12 * * * *" ]; then
67+
shard=$(( ($(date -u +%s) / 3600) % 6 ))
68+
candidates=$(jq -c --argjson shard "$shard" \
69+
'[.[] | select((.number % 6) == $shard) | {
70+
number: .number,
71+
head_sha: .head.sha
72+
}]' <<<"$pulls_json")
73+
else
74+
cutoff=$(date -u -d "1 hour ago" "+%Y-%m-%dT%H:%M:%SZ")
75+
# Hourly shards reconcile any candidates beyond this API budget.
76+
candidates=$(jq -c --arg cutoff "$cutoff" \
77+
'[.[] | select(.updated_at >= $cutoff) | {
78+
number: .number,
79+
head_sha: .head.sha
80+
}][0:100]' <<<"$pulls_json")
81+
fi
82+
fi
83+
84+
echo "Collected $(jq 'length' <<<"$candidates") pull request(s)."
85+
{
86+
echo "candidates<<EOF"
87+
echo "$candidates"
88+
echo "EOF"
89+
} >> "$GITHUB_OUTPUT"
90+
91+
- name: Validate pull request state
92+
id: validate
93+
env:
94+
GH_TOKEN: ${{ github.token }}
95+
REPO: ${{ github.repository }}
96+
CANDIDATES: ${{ steps.collect.outputs.candidates }}
97+
run: |
98+
set -euo pipefail
99+
100+
valid_numbers=()
101+
while IFS=$'\t' read -r pr_number expected_sha; do
102+
if [[ ! "$pr_number" =~ ^[1-9][0-9]*$ ]] ||
103+
[[ ! "$expected_sha" =~ ^[0-9a-f]{40}$ ]]; then
104+
echo "Skipping malformed pull request candidate."
105+
continue
106+
fi
107+
108+
if ! pr_json=$(gh api "repos/$REPO/pulls/$pr_number"); then
109+
echo "Pull request #$pr_number could not be fetched; skipping."
110+
continue
111+
fi
112+
113+
if ! jq -e \
114+
--arg repo "$REPO" \
115+
--arg sha "$expected_sha" \
116+
'.state == "open" and
117+
.base.repo.full_name == $repo and
118+
.head.sha == $sha and
119+
(.head.repo.full_name | type == "string")' \
120+
>/dev/null <<<"$pr_json"; then
121+
echo "Pull request #$pr_number changed or is no longer open; skipping."
122+
continue
123+
fi
124+
125+
valid_numbers+=("$pr_number")
126+
done < <(jq -r '.[] | [.number, .head_sha] | @tsv' <<<"$CANDIDATES")
127+
128+
if [ "${#valid_numbers[@]}" -eq 0 ]; then
129+
echo "has_prs=false" >> "$GITHUB_OUTPUT"
130+
exit 0
131+
fi
132+
133+
{
134+
echo "has_prs=true"
135+
echo "pr_numbers<<EOF"
136+
printf '%s\n' "${valid_numbers[@]}"
137+
echo "EOF"
138+
} >> "$GITHUB_OUTPUT"
139+
140+
- uses: actions/labeler@v4
141+
if: steps.validate.outputs.has_prs == 'true'
142+
with:
143+
repo-token: "${{ github.token }}"
144+
pr-number: ${{ steps.validate.outputs.pr_numbers }}

0 commit comments

Comments
 (0)