Skip to content

Commit d3b8fb9

Browse files
committed
Add per language configs and workflows
1 parent 7e0da2b commit d3b8fb9

25 files changed

Lines changed: 798 additions & 249 deletions
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
name: Generate baseline
2+
description: >
3+
Build a srcML baseline archive for a given (language, project) pair,
4+
publish it as a GitHub Release, and open a PR updating the per-project
5+
current_baseline_release pointer in config/<language>.toml.
6+
7+
inputs:
8+
language:
9+
description: "Language key — must match a config/<language>.toml file (e.g. c, cpp, csharp, java, python)."
10+
required: true
11+
project:
12+
description: "Project name — must match a [[projects]].name entry in config/<language>.toml."
13+
required: true
14+
srcml_version_override:
15+
description: "Override srcml release version (default: read from config)."
16+
required: false
17+
default: ""
18+
project_tag_override:
19+
description: "Override the project's VCS tag (default: read from config)."
20+
required: false
21+
default: ""
22+
dry_run:
23+
description: "If 'true', build the archive and upload it as a workflow artifact without creating a release or opening a PR."
24+
required: false
25+
default: "false"
26+
github_token:
27+
description: "Token used to publish the release and open the pointer PR. Defaults to GITHUB_TOKEN of the calling workflow."
28+
required: false
29+
default: ${{ github.token }}
30+
31+
runs:
32+
using: composite
33+
steps:
34+
- name: Install host deps
35+
shell: bash
36+
run: |
37+
sudo apt-get update
38+
sudo apt-get install -y zstd git curl ca-certificates jq
39+
40+
- name: Install mikefarah yq
41+
shell: bash
42+
run: |
43+
sudo curl -fsSL -o /usr/local/bin/yq \
44+
https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
45+
sudo chmod +x /usr/local/bin/yq
46+
yq --version
47+
48+
- name: Resolve config
49+
id: cfg
50+
shell: bash
51+
env:
52+
LANGUAGE: ${{ inputs.language }}
53+
PROJECT: ${{ inputs.project }}
54+
SV_OVERRIDE: ${{ inputs.srcml_version_override }}
55+
PT_OVERRIDE: ${{ inputs.project_tag_override }}
56+
run: |
57+
set -euo pipefail
58+
CFG="config/${LANGUAGE}.toml"
59+
if [ ! -f "$CFG" ]; then
60+
echo "::error::config file not found: $CFG"
61+
exit 1
62+
fi
63+
64+
NAMES="$(yq -p toml -r '.projects[].name' "$CFG")"
65+
if ! grep -Fxq "$PROJECT" <<<"$NAMES"; then
66+
echo "::error::project '$PROJECT' is not declared under .projects in $CFG"
67+
echo "available projects:"
68+
printf ' - %s\n' $NAMES
69+
exit 1
70+
fi
71+
72+
SV="$(yq -p toml '.srcml.version' "$CFG")"
73+
OS="$(lsb_release -rs)"
74+
PR="$(PROJECT="$PROJECT" yq -p toml '.projects[] | select(.name == strenv(PROJECT)) | .repo' "$CFG")"
75+
PT="$(PROJECT="$PROJECT" yq -p toml '.projects[] | select(.name == strenv(PROJECT)) | .tag' "$CFG")"
76+
SUBDIR="$(PROJECT="$PROJECT" yq -p toml '.projects[] | select(.name == strenv(PROJECT)) | .subdir // ""' "$CFG")"
77+
78+
# Flag precedence: language default + per-project append.
79+
LANG_FLAGS="$(yq -p toml -r '.srcml_flags | join(" ")' "$CFG")"
80+
PROJ_FLAGS="$(PROJECT="$PROJECT" yq -p toml -r '.projects[] | select(.name == strenv(PROJECT)) | (.srcml_flags_append // []) | join(" ")' "$CFG")"
81+
FLAGS="$LANG_FLAGS"
82+
[ -n "$PROJ_FLAGS" ] && FLAGS="$FLAGS $PROJ_FLAGS"
83+
84+
# dispatch overrides
85+
[ -n "$SV_OVERRIDE" ] && SV="$SV_OVERRIDE"
86+
[ -n "$PT_OVERRIDE" ] && PT="$PT_OVERRIDE"
87+
88+
TAG="baseline-${LANGUAGE}-${PROJECT}-${PT}-srcml-${SV}"
89+
90+
{
91+
echo "srcml_version=$SV"
92+
echo "srcml_os=$OS"
93+
echo "project_repo=$PR"
94+
echo "project_tag=$PT"
95+
echo "project_subdir=$SUBDIR"
96+
echo "srcml_flags=$FLAGS"
97+
echo "release_tag=$TAG"
98+
echo "xml_name=${TAG}.xml"
99+
echo "zst_name=${TAG}.xml.zst"
100+
echo "manifest_name=${TAG}.manifest.json"
101+
echo "log_name=${TAG}.generate.log"
102+
echo "config_path=$CFG"
103+
} >> "$GITHUB_OUTPUT"
104+
105+
- name: Install pinned srcml release
106+
shell: bash
107+
env:
108+
SV: ${{ steps.cfg.outputs.srcml_version }}
109+
OS: ${{ steps.cfg.outputs.srcml_os }}
110+
run: |
111+
set -euxo pipefail
112+
URL="https://github.com/srcML/srcML/releases/download/v${SV}/srcml_${SV}-1_ubuntu${OS}_amd64.deb"
113+
curl -fsSL -o srcml.deb "$URL"
114+
sudo apt-get install -y ./srcml.deb
115+
srcml --version
116+
117+
- name: Clone project source
118+
shell: bash
119+
env:
120+
PR: ${{ steps.cfg.outputs.project_repo }}
121+
PT: ${{ steps.cfg.outputs.project_tag }}
122+
run: |
123+
set -euxo pipefail
124+
git clone --depth 1 --branch "$PT" "$PR" project-src
125+
126+
- name: Generate baseline archive
127+
id: gen
128+
shell: bash
129+
env:
130+
SRCML_BIN: srcml
131+
SRCML_FLAGS: ${{ steps.cfg.outputs.srcml_flags }}
132+
SUBDIR: ${{ steps.cfg.outputs.project_subdir }}
133+
OUTPUT_XML: ${{ steps.cfg.outputs.xml_name }}
134+
OUTPUT_ZST: ${{ steps.cfg.outputs.zst_name }}
135+
LOG_FILE: ${{ steps.cfg.outputs.log_name }}
136+
run: |
137+
set -euo pipefail
138+
if [ -n "$SUBDIR" ]; then
139+
INPUT_DIR="project-src/$SUBDIR"
140+
if [ ! -d "$INPUT_DIR" ]; then
141+
echo "::error::configured subdir '$SUBDIR' does not exist under the cloned project"
142+
exit 1
143+
fi
144+
else
145+
INPUT_DIR="project-src"
146+
fi
147+
export INPUT_DIR
148+
./scripts/generate_baseline.sh
149+
150+
- name: Emit manifest
151+
id: manifest
152+
shell: bash
153+
env:
154+
LANGUAGE: ${{ inputs.language }}
155+
PROJECT: ${{ inputs.project }}
156+
SV: ${{ steps.cfg.outputs.srcml_version }}
157+
PT: ${{ steps.cfg.outputs.project_tag }}
158+
FLAGS: ${{ steps.cfg.outputs.srcml_flags }}
159+
RAW: ${{ steps.gen.outputs.raw_bytes }}
160+
ZST: ${{ steps.gen.outputs.zst_bytes }}
161+
SHA: ${{ steps.gen.outputs.sha256 }}
162+
ZST_NAME: ${{ steps.cfg.outputs.zst_name }}
163+
MANIFEST_NAME: ${{ steps.cfg.outputs.manifest_name }}
164+
run: |
165+
jq -n \
166+
--arg language "$LANGUAGE" \
167+
--arg project "$PROJECT" \
168+
--arg srcml_version "$SV" \
169+
--arg project_tag "$PT" \
170+
--arg flags "$FLAGS" \
171+
--arg asset_name "$ZST_NAME" \
172+
--arg bytes_raw "$RAW" \
173+
--arg bytes_zst "$ZST" \
174+
--arg sha256 "$SHA" \
175+
--arg generated_at "$(date --iso-8601=seconds)" \
176+
--arg runner_os "$(lsb_release -ds 2>/dev/null || uname -a)" \
177+
'{
178+
language:$language,
179+
project:$project,
180+
srcml_version:$srcml_version,
181+
project_tag:$project_tag,
182+
flags:$flags,
183+
asset_name:$asset_name,
184+
bytes_raw:($bytes_raw|tonumber),
185+
bytes_compressed:($bytes_zst|tonumber),
186+
sha256:$sha256,
187+
generated_at:$generated_at,
188+
runner_os:$runner_os
189+
}' > "$MANIFEST_NAME"
190+
cat "$MANIFEST_NAME"
191+
192+
- name: Upload scratch artifact (dry_run path)
193+
if: ${{ inputs.dry_run == 'true' }}
194+
uses: actions/upload-artifact@v4
195+
with:
196+
name: baseline-dry-run-${{ steps.cfg.outputs.release_tag }}
197+
path: |
198+
${{ steps.cfg.outputs.zst_name }}
199+
${{ steps.cfg.outputs.manifest_name }}
200+
${{ steps.cfg.outputs.log_name }}
201+
retention-days: 14
202+
203+
- name: Publish GitHub Release
204+
if: ${{ inputs.dry_run != 'true' }}
205+
shell: bash
206+
env:
207+
GH_TOKEN: ${{ inputs.github_token }}
208+
TAG: ${{ steps.cfg.outputs.release_tag }}
209+
LANGUAGE: ${{ inputs.language }}
210+
PROJECT: ${{ inputs.project }}
211+
SV: ${{ steps.cfg.outputs.srcml_version }}
212+
PT: ${{ steps.cfg.outputs.project_tag }}
213+
ZST_NAME: ${{ steps.cfg.outputs.zst_name }}
214+
MANIFEST_NAME: ${{ steps.cfg.outputs.manifest_name }}
215+
LOG_NAME: ${{ steps.cfg.outputs.log_name }}
216+
run: |
217+
set -euxo pipefail
218+
if gh release view "$TAG" >/dev/null 2>&1; then
219+
gh release upload "$TAG" "$ZST_NAME" "$MANIFEST_NAME" "$LOG_NAME" --clobber
220+
else
221+
gh release create "$TAG" \
222+
--title "Baseline: ${LANGUAGE}/${PROJECT} ${PT} / srcml ${SV}" \
223+
--notes "Baseline srcML archive. language=${LANGUAGE}, project=${PROJECT}, project_tag=${PT}, srcml=${SV}. See ${MANIFEST_NAME} for sha256 and flags." \
224+
--latest=false \
225+
"$ZST_NAME" "$MANIFEST_NAME" "$LOG_NAME"
226+
fi
227+
228+
- name: Update per-project pointer
229+
if: ${{ inputs.dry_run != 'true' }}
230+
shell: bash
231+
env:
232+
CFG: ${{ steps.cfg.outputs.config_path }}
233+
PROJECT: ${{ inputs.project }}
234+
TAG: ${{ steps.cfg.outputs.release_tag }}
235+
run: |
236+
yq -i -p toml -o toml '
237+
(.projects[] | select(.name == strenv(PROJECT)) | .current_baseline_release) = strenv(TAG)
238+
' "$CFG"
239+
240+
- name: Open baseline pointer PR
241+
if: ${{ inputs.dry_run != 'true' }}
242+
uses: peter-evans/create-pull-request@v6
243+
with:
244+
token: ${{ inputs.github_token }}
245+
commit-message: "chore: point ${{ inputs.language }}/${{ inputs.project }} baseline to ${{ steps.cfg.outputs.release_tag }}"
246+
branch: baseline-pointer/${{ steps.cfg.outputs.release_tag }}
247+
title: "Update baseline pointer → ${{ steps.cfg.outputs.release_tag }}"
248+
body: |
249+
Automated PR to update `${{ steps.cfg.outputs.config_path }}` → the `[[projects]]` entry for `${{ inputs.project }}`'s `current_baseline_release`.
250+
251+
- language: ${{ inputs.language }}
252+
- project: ${{ inputs.project }}
253+
- project tag: ${{ steps.cfg.outputs.project_tag }}
254+
- srcml: ${{ steps.cfg.outputs.srcml_version }}
255+
- release tag: ${{ steps.cfg.outputs.release_tag }}
256+
257+
Release assets are published. Merge to make downstream runs use this baseline.
258+
add-paths: |
259+
${{ steps.cfg.outputs.config_path }}

.github/workflows/baseline-c.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Generate baseline — C
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
project:
7+
description: "Project from config/c.toml to generate a baseline for"
8+
required: true
9+
type: choice
10+
options:
11+
- linux
12+
srcml_version:
13+
description: "Override srcml release version (default: read from config)"
14+
required: false
15+
default: ""
16+
project_tag:
17+
description: "Override project tag (default: read from config)"
18+
required: false
19+
default: ""
20+
dry_run:
21+
description: "Build the archive but skip publishing a release / opening a PR"
22+
required: false
23+
default: "false"
24+
25+
permissions:
26+
contents: write
27+
pull-requests: write
28+
29+
concurrency:
30+
group: baseline-c-${{ inputs.project }}-${{ inputs.srcml_version }}-${{ inputs.project_tag }}
31+
cancel-in-progress: false
32+
33+
jobs:
34+
generate:
35+
runs-on: ubuntu-latest
36+
timeout-minutes: 300
37+
steps:
38+
- uses: actions/checkout@v4
39+
- uses: ./.github/actions/generate-baseline
40+
with:
41+
language: c
42+
project: ${{ inputs.project }}
43+
srcml_version_override: ${{ inputs.srcml_version }}
44+
project_tag_override: ${{ inputs.project_tag }}
45+
dry_run: ${{ inputs.dry_run }}

.github/workflows/baseline-cpp.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Generate baseline — C++
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
project:
7+
description: "Project from config/cpp.toml to generate a baseline for"
8+
required: true
9+
type: choice
10+
options:
11+
- llvm
12+
srcml_version:
13+
description: "Override srcml release version (default: read from config)"
14+
required: false
15+
default: ""
16+
project_tag:
17+
description: "Override project tag (default: read from config)"
18+
required: false
19+
default: ""
20+
dry_run:
21+
description: "Build the archive but skip publishing a release / opening a PR"
22+
required: false
23+
default: "false"
24+
25+
permissions:
26+
contents: write
27+
pull-requests: write
28+
29+
concurrency:
30+
group: baseline-cpp-${{ inputs.project }}-${{ inputs.srcml_version }}-${{ inputs.project_tag }}
31+
cancel-in-progress: false
32+
33+
jobs:
34+
generate:
35+
runs-on: ubuntu-latest
36+
timeout-minutes: 300
37+
steps:
38+
- uses: actions/checkout@v4
39+
- uses: ./.github/actions/generate-baseline
40+
with:
41+
language: cpp
42+
project: ${{ inputs.project }}
43+
srcml_version_override: ${{ inputs.srcml_version }}
44+
project_tag_override: ${{ inputs.project_tag }}
45+
dry_run: ${{ inputs.dry_run }}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Generate baseline — C#
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
project:
7+
description: "Project from config/csharp.toml to generate a baseline for"
8+
required: true
9+
type: choice
10+
options:
11+
- roslyn
12+
srcml_version:
13+
description: "Override srcml release version (default: read from config)"
14+
required: false
15+
default: ""
16+
project_tag:
17+
description: "Override project tag (default: read from config)"
18+
required: false
19+
default: ""
20+
dry_run:
21+
description: "Build the archive but skip publishing a release / opening a PR"
22+
required: false
23+
default: "false"
24+
25+
permissions:
26+
contents: write
27+
pull-requests: write
28+
29+
concurrency:
30+
group: baseline-csharp-${{ inputs.project }}-${{ inputs.srcml_version }}-${{ inputs.project_tag }}
31+
cancel-in-progress: false
32+
33+
jobs:
34+
generate:
35+
runs-on: ubuntu-latest
36+
timeout-minutes: 300
37+
steps:
38+
- uses: actions/checkout@v4
39+
- uses: ./.github/actions/generate-baseline
40+
with:
41+
language: csharp
42+
project: ${{ inputs.project }}
43+
srcml_version_override: ${{ inputs.srcml_version }}
44+
project_tag_override: ${{ inputs.project_tag }}
45+
dry_run: ${{ inputs.dry_run }}

0 commit comments

Comments
 (0)