Skip to content

Commit 25c6595

Browse files
Add Ubuntu support (closes #226)
1 parent 5c99311 commit 25c6595

19 files changed

Lines changed: 17892 additions & 17733 deletions

.github/workflows/ci.yml

Lines changed: 60 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,60 @@
1-
name: CI
2-
3-
on:
4-
push:
5-
pull_request:
6-
7-
jobs:
8-
build-and-test:
9-
runs-on: windows-latest
10-
11-
steps:
12-
- name: Checkout code
13-
uses: actions/checkout@v4
14-
with:
15-
fetch-depth: 0
16-
persist-credentials: true
17-
18-
- name: Run code formatter and commit changes
19-
run: |
20-
# Run project formatter
21-
.\format.ps1
22-
# Configure Git for automated commits
23-
git config user.name "github-actions[bot]"
24-
git config user.email "github-actions[bot]@users.noreply.github.com"
25-
$changes = git status --porcelain
26-
if ($changes) {
27-
git add -A
28-
git commit -m "chore: format and lint with Clang."
29-
git push
30-
} else {
31-
Write-Host "No changes to commit"
32-
}
33-
34-
- name: Build interpreter and extensions
35-
run: .\build.ps1
36-
37-
- name: Run tests
38-
run: .\tests\test.ps1
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
build-and-test-windows:
9+
runs-on: windows-latest
10+
11+
steps:
12+
- name: Checkout code
13+
uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 0
16+
persist-credentials: true
17+
18+
- name: Run code formatter and commit changes
19+
run: |
20+
# Run project formatter
21+
.\format.ps1
22+
# Configure Git for automated commits
23+
git config user.name "github-actions[bot]"
24+
git config user.email "github-actions[bot]@users.noreply.github.com"
25+
$changes = git status --porcelain
26+
if ($changes) {
27+
git add -A
28+
git commit -m "chore: format and lint with Clang."
29+
git push
30+
} else {
31+
Write-Host "No changes to commit"
32+
}
33+
34+
- name: Build interpreter and extensions
35+
run: .\build.ps1
36+
37+
- name: Run tests
38+
run: .\tests\test.ps1
39+
40+
build-and-test-ubuntu:
41+
runs-on: ubuntu-22.04
42+
43+
steps:
44+
- name: Checkout code
45+
uses: actions/checkout@v4
46+
with:
47+
fetch-depth: 0
48+
49+
- name: Install dependencies
50+
run: |
51+
sudo apt-get update
52+
sudo apt-get install -y clang lld powershell
53+
54+
- name: Build interpreter and extensions
55+
shell: pwsh
56+
run: ./build.ps1
57+
58+
- name: Run tests
59+
shell: pwsh
60+
run: ./tests/test.ps1

.github/workflows/release.yml

Lines changed: 129 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,130 @@
1-
name: Release
2-
3-
on:
4-
push:
5-
tags:
6-
- '*'
7-
workflow_dispatch:
8-
9-
permissions:
10-
contents: write
11-
issues: write
12-
13-
jobs:
14-
release:
15-
runs-on: windows-latest
16-
17-
steps:
18-
- name: Checkout repository
19-
uses: actions/checkout@v4
20-
with:
21-
fetch-depth: 0
22-
persist-credentials: true
23-
24-
- name: Get tag and commit message
25-
id: tag-info
26-
shell: pwsh
27-
run: |
28-
$tag = ($env:GITHUB_REF -split '/')[ -1 ]
29-
Write-Host "Tag: $tag"
30-
git fetch --tags
31-
$commit = (git rev-list -n 1 $tag).Trim()
32-
Write-Host "Commit: $commit"
33-
$rawBody = git show -s --format=%B $commit
34-
# Strip the first non-blank line (commit summary) and any intervening blank lines,
35-
# starting notes from the second non-blank line onward.
36-
$lines = $rawBody -split '(?:\r\n|\n|\r)'
37-
$nonBlank = @()
38-
for ($i = 0; $i -lt $lines.Count; $i++) {
39-
if ($lines[$i].Trim() -ne '') { $nonBlank += $i }
40-
}
41-
if ($nonBlank.Count -ge 2) {
42-
$start = $nonBlank[1]
43-
$notesLines = $lines[$start..($lines.Count - 1)]
44-
$body = ($notesLines -join "`n")
45-
} else {
46-
# No body content beyond a single-line summary
47-
$body = ''
48-
}
49-
$norm = $tag -replace '^v',''
50-
# Use a unique delimiter for multiline output to GITHUB_OUTPUT to avoid collisions
51-
$delim = [guid]::NewGuid().ToString()
52-
Add-Content -Path $env:GITHUB_OUTPUT -Value "tag=$tag"
53-
Add-Content -Path $env:GITHUB_OUTPUT -Value "body<<$delim"
54-
Add-Content -Path $env:GITHUB_OUTPUT -Value $body
55-
Add-Content -Path $env:GITHUB_OUTPUT -Value $delim
56-
Add-Content -Path $env:GITHUB_OUTPUT -Value "norm_tag=$norm"
57-
58-
- name: Create GitHub release
59-
uses: actions/create-release@v1
60-
env:
61-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62-
with:
63-
tag_name: ${{ steps.tag-info.outputs.tag }}
64-
release_name: ${{ steps.tag-info.outputs.norm_tag }}
65-
body: ${{ steps.tag-info.outputs.body }}
66-
draft: false
67-
prerelease: false
68-
69-
- name: Update docs/CHANGELOG.html and close milestone
70-
shell: pwsh
71-
env:
72-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
73-
run: |
74-
$tag = '${{ steps.tag-info.outputs.tag }}'
75-
$norm = '${{ steps.tag-info.outputs.norm_tag }}'
76-
git fetch --tags --prune
77-
$commit = (git rev-list -n 1 $tag).Trim()
78-
$rawBody = git show -s --format=%B $commit
79-
# Strip the first non-blank line (commit summary) and any intervening blank lines,
80-
# starting notes from the second non-blank line onward.
81-
$lines = $rawBody -split '(?:\r\n|\n|\r)'
82-
$nonBlank = @()
83-
for ($i = 0; $i -lt $lines.Count; $i++) {
84-
if ($lines[$i].Trim() -ne '') { $nonBlank += $i }
85-
}
86-
if ($nonBlank.Count -ge 2) {
87-
$start = $nonBlank[1]
88-
$notesLines = $lines[$start..($lines.Count - 1)]
89-
$body = ($notesLines -join "`n")
90-
} else {
91-
$body = ''
92-
}
93-
$path = 'Prefix/docs/CHANGELOG.html'
94-
if (-not (Test-Path $path)) { Write-Error "$path not found"; exit 1 }
95-
$text = Get-Content -Raw -Encoding UTF8 $path
96-
$regex = [regex]::new('(?s)(<script id="md" type="text/markdown">\s*)(?<md>.*?)(\s*</script>)')
97-
$match = $regex.Match($text)
98-
if (-not $match.Success) { Write-Error "Embedded markdown block not found in $path"; exit 1 }
99-
$prefix = $match.Groups[1].Value
100-
$md = $match.Groups['md'].Value
101-
$suffix = $match.Groups[3].Value
102-
if ($md -match '(?m)^\s*##\s*' + [regex]::Escape($norm) + '\s*$') {
103-
Write-Host "CHANGELOG already contains $norm; skipping update."
104-
exit 0
105-
}
106-
$sepMatches = [regex]::Matches($md, '^[ \t]*---[ \t]*$', [System.Text.RegularExpressions.RegexOptions]::Multiline)
107-
if ($sepMatches.Count -ge 2) { $insIndex = $sepMatches[1].Index + $sepMatches[1].Length } elseif ($sepMatches.Count -ge 1) { $insIndex = $sepMatches[0].Index + $sepMatches[0].Length } else { $insIndex = 0 }
108-
# Insert the commit message body exactly as provided (no added headers or placeholders).
109-
$sectionBody = $body
110-
$section = "## $norm`n`n" + $sectionBody + "`n`n---`n`n"
111-
$new_md = $md.Substring(0, $insIndex) + $section + $md.Substring($insIndex)
112-
$new_text = $text.Substring(0,$match.Index) + $prefix + $new_md + $suffix + $text.Substring($match.Index + $match.Length)
113-
Set-Content -Path $path -Value $new_text -Encoding UTF8
114-
git config user.name "github-actions[bot]"
115-
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
116-
git add $path
117-
git commit -m "chore(release): update CHANGELOG for $tag" || Write-Host "No changelog changes"
118-
git remote set-head origin --auto
119-
$default_branch = (git symbolic-ref refs/remotes/origin/HEAD).Replace('refs/remotes/origin/','')
120-
git push origin HEAD:$default_branch
121-
# close matching open milestone (exact title match)
122-
$repo = $env:GITHUB_REPOSITORY
123-
$token = $env:GITHUB_TOKEN
124-
$miles = Invoke-RestMethod -Headers @{ Authorization = "token $token"; 'User-Agent' = 'github-actions' } -Uri "https://api.github.com/repos/$repo/milestones?state=open&per_page=100" -Method Get
125-
foreach ($m in $miles) {
126-
if ($m.title -eq $norm) {
127-
Write-Host "Closing milestone $($m.title) (number $($m.number))"
128-
Invoke-RestMethod -Headers @{ Authorization = "token $token"; 'User-Agent' = 'github-actions' } -Method Patch -Uri "https://api.github.com/repos/$repo/milestones/$($m.number)" -Body (@{ state = 'closed' } | ConvertTo-Json)
129-
}
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
issues: write
12+
13+
jobs:
14+
release:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
persist-credentials: true
23+
24+
- name: Get tag and commit message
25+
id: tag-info
26+
shell: pwsh
27+
run: |
28+
$tag = ($env:GITHUB_REF -split '/')[ -1 ]
29+
Write-Host "Tag: $tag"
30+
git fetch --tags
31+
$commit = (git rev-list -n 1 $tag).Trim()
32+
Write-Host "Commit: $commit"
33+
$rawBody = git show -s --format=%B $commit
34+
# Strip the first non-blank line (commit summary) and any intervening blank lines,
35+
# starting notes from the second non-blank line onward.
36+
$lines = $rawBody -split '(?:\r\n|\n|\r)'
37+
$nonBlank = @()
38+
for ($i = 0; $i -lt $lines.Count; $i++) {
39+
if ($lines[$i].Trim() -ne '') { $nonBlank += $i }
40+
}
41+
if ($nonBlank.Count -ge 2) {
42+
$start = $nonBlank[1]
43+
$notesLines = $lines[$start..($lines.Count - 1)]
44+
$body = ($notesLines -join "`n")
45+
} else {
46+
# No body content beyond a single-line summary
47+
$body = ''
48+
}
49+
$norm = $tag -replace '^v',''
50+
# Use a unique delimiter for multiline output to GITHUB_OUTPUT to avoid collisions
51+
$delim = [guid]::NewGuid().ToString()
52+
Add-Content -Path $env:GITHUB_OUTPUT -Value "tag=$tag"
53+
Add-Content -Path $env:GITHUB_OUTPUT -Value "body<<$delim"
54+
Add-Content -Path $env:GITHUB_OUTPUT -Value $body
55+
Add-Content -Path $env:GITHUB_OUTPUT -Value $delim
56+
Add-Content -Path $env:GITHUB_OUTPUT -Value "norm_tag=$norm"
57+
58+
- name: Create GitHub release
59+
uses: actions/create-release@v1
60+
env:
61+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62+
with:
63+
tag_name: ${{ steps.tag-info.outputs.tag }}
64+
release_name: ${{ steps.tag-info.outputs.norm_tag }}
65+
body: ${{ steps.tag-info.outputs.body }}
66+
draft: false
67+
prerelease: false
68+
69+
- name: Update docs/CHANGELOG.html and close milestone
70+
shell: pwsh
71+
env:
72+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
73+
run: |
74+
$tag = '${{ steps.tag-info.outputs.tag }}'
75+
$norm = '${{ steps.tag-info.outputs.norm_tag }}'
76+
git fetch --tags --prune
77+
$commit = (git rev-list -n 1 $tag).Trim()
78+
$rawBody = git show -s --format=%B $commit
79+
# Strip the first non-blank line (commit summary) and any intervening blank lines,
80+
# starting notes from the second non-blank line onward.
81+
$lines = $rawBody -split '(?:\r\n|\n|\r)'
82+
$nonBlank = @()
83+
for ($i = 0; $i -lt $lines.Count; $i++) {
84+
if ($lines[$i].Trim() -ne '') { $nonBlank += $i }
85+
}
86+
if ($nonBlank.Count -ge 2) {
87+
$start = $nonBlank[1]
88+
$notesLines = $lines[$start..($lines.Count - 1)]
89+
$body = ($notesLines -join "`n")
90+
} else {
91+
$body = ''
92+
}
93+
$path = 'Prefix/docs/CHANGELOG.html'
94+
if (-not (Test-Path $path)) { Write-Error "$path not found"; exit 1 }
95+
$text = Get-Content -Raw -Encoding UTF8 $path
96+
$regex = [regex]::new('(?s)(<script id="md" type="text/markdown">\s*)(?<md>.*?)(\s*</script>)')
97+
$match = $regex.Match($text)
98+
if (-not $match.Success) { Write-Error "Embedded markdown block not found in $path"; exit 1 }
99+
$prefix = $match.Groups[1].Value
100+
$md = $match.Groups['md'].Value
101+
$suffix = $match.Groups[3].Value
102+
if ($md -match '(?m)^\s*##\s*' + [regex]::Escape($norm) + '\s*$') {
103+
Write-Host "CHANGELOG already contains $norm; skipping update."
104+
exit 0
105+
}
106+
$sepMatches = [regex]::Matches($md, '^[ \t]*---[ \t]*$', [System.Text.RegularExpressions.RegexOptions]::Multiline)
107+
if ($sepMatches.Count -ge 2) { $insIndex = $sepMatches[1].Index + $sepMatches[1].Length } elseif ($sepMatches.Count -ge 1) { $insIndex = $sepMatches[0].Index + $sepMatches[0].Length } else { $insIndex = 0 }
108+
# Insert the commit message body exactly as provided (no added headers or placeholders).
109+
$sectionBody = $body
110+
$section = "## $norm`n`n" + $sectionBody + "`n`n---`n`n"
111+
$new_md = $md.Substring(0, $insIndex) + $section + $md.Substring($insIndex)
112+
$new_text = $text.Substring(0,$match.Index) + $prefix + $new_md + $suffix + $text.Substring($match.Index + $match.Length)
113+
Set-Content -Path $path -Value $new_text -Encoding UTF8
114+
git config user.name "github-actions[bot]"
115+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
116+
git add $path
117+
git commit -m "chore(release): update CHANGELOG for $tag" || Write-Host "No changelog changes"
118+
git remote set-head origin --auto
119+
$default_branch = (git symbolic-ref refs/remotes/origin/HEAD).Replace('refs/remotes/origin/','')
120+
git push origin HEAD:$default_branch
121+
# close matching open milestone (exact title match)
122+
$repo = $env:GITHUB_REPOSITORY
123+
$token = $env:GITHUB_TOKEN
124+
$miles = Invoke-RestMethod -Headers @{ Authorization = "token $token"; 'User-Agent' = 'github-actions' } -Uri "https://api.github.com/repos/$repo/milestones?state=open&per_page=100" -Method Get
125+
foreach ($m in $miles) {
126+
if ($m.title -eq $norm) {
127+
Write-Host "Closing milestone $($m.title) (number $($m.number))"
128+
Invoke-RestMethod -Headers @{ Authorization = "token $token"; 'User-Agent' = 'github-actions' } -Method Patch -Uri "https://api.github.com/repos/$repo/milestones/$($m.number)" -Body (@{ state = 'closed' } | ConvertTo-Json)
129+
}
130130
}

.gitignore

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
# Ignore binaries (both executables and libraries)
2-
*.exe
3-
*.app
4-
*.lib
5-
*.dll
6-
*.so
7-
*.dylib
1+
# Ignore binaries (both executables and libraries)
2+
*.exe
3+
*.app
4+
*.lib
5+
*.dll
6+
*.so
7+
*.dylib
8+
prefix

0 commit comments

Comments
 (0)