Skip to content

Commit 77b76a7

Browse files
authored
Add CI workflow. (#5)
1 parent fbe44d1 commit 77b76a7

13 files changed

Lines changed: 1334 additions & 0 deletions

‎.github/workflows/build-sounds.yml‎

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
name: Build sound packages
2+
3+
# Builds the FreeSWITCH sound tarballs with dist.pl and publishes each
4+
# package at its own version as a dedicated GitHub Release.
5+
#
6+
# dist.pl produces files named:
7+
# freeswitch-sounds-<voice>-<rate>-<version>.tar.gz (+ .md5/.sha1/.sha256)
8+
# e.g. freeswitch-sounds-en-us-callie-48000-1.0.53.tar.gz
9+
# freeswitch-sounds-music-48000-1.0.52.tar.gz
10+
#
11+
# We group those files by (voice, version) and publish one release per
12+
# package-version, tagged "<voice>-<version>" (e.g. "en-us-callie-1.0.53",
13+
# "music-1.0.52"). The version is whatever dist.pl built, so tags can never
14+
# drift from the artifacts. Bumping a version in dist.pl cuts a brand-new
15+
# release and leaves every previous version frozen and downloadable at:
16+
#
17+
# https://github.com/${{ github.repository }}/releases/download/<voice>-<version>/<filename>
18+
#
19+
# This replaces files.freeswitch.org as the source of sound packages.
20+
21+
on:
22+
workflow_dispatch:
23+
inputs:
24+
packages:
25+
description: >-
26+
Space-separated package dirs to build, matching dist.pl's package
27+
list (voices and/or "music"), e.g. "en/us/callie music".
28+
Leave empty to build every package.
29+
required: false
30+
default: ""
31+
32+
# Needed so the workflow can create tags, releases, and upload assets.
33+
permissions:
34+
contents: write
35+
36+
jobs:
37+
build-and-release:
38+
runs-on: ubuntu-latest
39+
steps:
40+
- name: Checkout
41+
uses: actions/checkout@v7
42+
43+
- name: Install audio tooling
44+
run: |
45+
sudo apt-get update
46+
sudo apt-get install -y sox normalize-audio libsox-fmt-all
47+
48+
- name: Build sound packages
49+
env:
50+
# Passed via env (not inlined into the script) to avoid shell
51+
# injection from the workflow input. Unquoted on use so it splits
52+
# into separate args; empty => dist.pl builds everything.
53+
PACKAGES: ${{ inputs.packages }}
54+
run: |
55+
set -euo pipefail
56+
perl dist.pl $PACKAGES
57+
echo "---- built artifacts ----"
58+
ls -1 freeswitch-sounds-*.tar.gz
59+
60+
- name: Publish per-package-version releases
61+
env:
62+
GH_TOKEN: ${{ github.token }}
63+
run: |
64+
set -euo pipefail
65+
shopt -s nullglob
66+
67+
# Group built files by their (voice, version) -> release tag.
68+
declare -A TAG_FILES
69+
for f in freeswitch-sounds-*.tar.gz; do
70+
base=${f#freeswitch-sounds-} # <voice>-<rate>-<version>.tar.gz
71+
base=${base%.tar.gz} # <voice>-<rate>-<version>
72+
if [[ $base =~ ^(.+)-(8000|16000|32000|48000)-([0-9][0-9.]*)$ ]]; then
73+
voice=${BASH_REMATCH[1]}
74+
version=${BASH_REMATCH[3]}
75+
tag="${voice}-${version}"
76+
# tarball + any checksum sidecars dist.pl generated
77+
for path in "$f" "$f".md5 "$f".sha1 "$f".sha256; do
78+
[[ -e $path ]] && TAG_FILES[$tag]+=" $path"
79+
done
80+
else
81+
echo "WARN: cannot parse '$f', skipping" >&2
82+
fi
83+
done
84+
85+
if [[ ${#TAG_FILES[@]} -eq 0 ]]; then
86+
echo "No built packages found to publish." >&2
87+
exit 1
88+
fi
89+
90+
for tag in "${!TAG_FILES[@]}"; do
91+
read -ra files <<< "${TAG_FILES[$tag]}"
92+
echo "== ${tag}: ${#files[@]} file(s) =="
93+
if gh release view "$tag" >/dev/null 2>&1; then
94+
echo "Release $tag exists; updating assets (clobber)."
95+
gh release upload "$tag" "${files[@]}" --clobber
96+
else
97+
echo "Creating release $tag."
98+
# --latest=false: per-package releases must not fight over the
99+
# repo-wide "Latest" badge.
100+
gh release create "$tag" "${files[@]}" \
101+
--latest=false \
102+
--title "$tag" \
103+
--notes "FreeSWITCH sound package built by CI from dist.pl. Download a specific sample rate via /releases/download/${tag}/<filename>."
104+
fi
105+
done
106+
107+
- name: Upload artifacts (build record)
108+
uses: actions/upload-artifact@v7
109+
with:
110+
name: sound-packages
111+
path: |
112+
freeswitch-sounds-*.tar.gz
113+
freeswitch-sounds-*.tar.gz.md5
114+
freeswitch-sounds-*.tar.gz.sha1
115+
freeswitch-sounds-*.tar.gz.sha256
116+
if-no-files-found: error
117+
retention-days: 7
118+
119+
# Windows MSI installers, built from the tarballs produced above and attached
120+
# to the same per-package-version releases. WiX scaffolding lives in windows/.
121+
build-msi:
122+
name: Build Windows MSIs
123+
needs: build-and-release
124+
runs-on: windows-latest
125+
steps:
126+
- name: Checkout
127+
uses: actions/checkout@v7
128+
129+
- name: Download built sound tarballs
130+
uses: actions/download-artifact@v8
131+
with:
132+
name: sound-packages
133+
path: dist
134+
135+
- name: Install WiX Toolset v3
136+
shell: pwsh
137+
run: |
138+
choco install wixtoolset -y --no-progress
139+
# Discover the install dir (version may vary) and expose it via WIX so
140+
# build-msi.ps1 / the wixproj resolve Wix.targets and the WiX tools.
141+
$root = Get-ChildItem "C:\Program Files (x86)" -Directory -Filter "WiX Toolset v3*" |
142+
Sort-Object Name -Descending | Select-Object -First 1
143+
if (-not $root) { throw "WiX Toolset v3 not found after install" }
144+
"WIX=$($root.FullName)\" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
145+
Write-Host "WIX=$($root.FullName)\"
146+
147+
- name: Add MSBuild to PATH
148+
uses: microsoft/setup-msbuild@v3
149+
150+
- name: Build MSIs
151+
shell: pwsh
152+
run: |
153+
$ErrorActionPreference = "Stop"
154+
$tarballs = Get-ChildItem dist -Filter "freeswitch-sounds-*.tar.gz"
155+
if ($tarballs.Count -eq 0) { throw "No tarballs found in dist/" }
156+
foreach ($t in $tarballs) {
157+
Write-Host "==== $($t.Name) ===="
158+
./windows/build-msi.ps1 -Tarball $t.FullName
159+
}
160+
Write-Host "---- built MSIs ----"
161+
Get-ChildItem windows/x64 -Filter *.msi | Format-Table Name, Length -AutoSize
162+
163+
- name: Publish MSIs to per-package-version releases
164+
shell: pwsh
165+
env:
166+
GH_TOKEN: ${{ github.token }}
167+
run: |
168+
$ErrorActionPreference = "Stop"
169+
$msis = Get-ChildItem windows/x64 -Filter *.msi
170+
if ($msis.Count -eq 0) { throw "No MSIs were produced" }
171+
foreach ($m in $msis) {
172+
if ($m.Name -notmatch '^FreeSWITCH-Sounds-(.+)-([0-9][0-9.]*)-(8000|16000|32000|48000)Hz\.msi$') {
173+
Write-Host "WARN: cannot parse '$($m.Name)', skipping"
174+
continue
175+
}
176+
$tag = "$($Matches[1])-$($Matches[2])" # <voice>-<version>, matches the release tag
177+
Write-Host "Uploading $($m.Name) -> release $tag"
178+
gh release upload $tag $m.FullName --clobber
179+
if ($LASTEXITCODE -ne 0) { throw "gh release upload failed for $tag" }
180+
}
181+
182+
- name: Upload MSIs (build record)
183+
uses: actions/upload-artifact@v7
184+
with:
185+
name: sound-msis
186+
path: windows/x64/*.msi
187+
if-no-files-found: error
188+
retention-days: 7

‎windows/.gitignore‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Visual Studio
2+
.vs/
3+
4+
# WiX build intermediates / outputs
5+
Fragments/
6+
bin/
7+
obj/
8+
x64/
9+
*.msi
10+
*.wixobj
11+
*.wixpdb
12+
13+
# Extracted sound payloads (recreated at build time)
14+
libs/
15+
16+
# Note: build/sounds_version.txt and build/moh_version.txt are generated from
17+
# dist.pl by gen-version-files.pl but ARE committed (like freeswitch), so a plain
18+
# `msbuild` works with no prerequisites. Re-run the generator after bumping a
19+
# version in dist.pl; CI regenerates them on every build.

‎windows/Product.wxs‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!-- Platform specific variables -->
3+
<?define ProductName = "FreeSWITCH Sounds - $(var.SoundPrimaryName) $(var.SoundQuality)Hz $(var.SoundVersion)" ?>
4+
<?define ComponentGroup = "FreeSWITCHSoundFiles$(var.SoundSuffix)" ?>
5+
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
6+
<Product Id="*" Name="$(var.ProductName)" Language="1033" Version="$(var.SoundVersion)" Manufacturer="FreeSWITCH" UpgradeCode="$(var.SoundUpgradeCode)">
7+
<Package InstallerVersion="200" Compressed="yes" />
8+
9+
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
10+
11+
<MediaTemplate EmbedCab="yes" />
12+
13+
<Directory Id="TARGETDIR" Name="SourceDir">
14+
<Directory Id="ProgramFiles64Folder">
15+
<Directory Id="FREESWITCHFOLDER" Name="FreeSWITCH">
16+
<Directory Id="SOUNDLOCATION" Name="sounds">
17+
</Directory>
18+
</Directory>
19+
</Directory>
20+
</Directory>
21+
22+
<Feature Id="ProductFeature" Title="$(var.ProductName)" Level="1">
23+
<ComponentGroupRef Id="$(var.ComponentGroup)" />
24+
</Feature>
25+
26+
<UIRef Id="WixUI_Minimal" />
27+
<WixVariable Id="WixUILicenseRtf" Value="$(var.BaseDir)docs/COPYING.rtf" />
28+
</Product>
29+
</Wix>

‎windows/README.md‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Windows MSI packaging
2+
3+
Builds Windows installers (`.msi`) for the FreeSWITCH sound packages. Ported
4+
from `freeswitch` `w32/Setup/Sounds` so this repository can produce its own
5+
Windows artifacts without cloning freeswitch and without `files.freeswitch.org`.
6+
7+
## Contents
8+
9+
| File | Purpose |
10+
|------|---------|
11+
| `Setup.Sounds.2017.sln` / `.wixproj` | WiX v3 project that produces one MSI per package+rate |
12+
| `Product.wxs` | WiX product definition (installs into `Program Files\FreeSWITCH\sounds`) |
13+
| `basedir.props` | Sets `BaseDir` to this `windows/` folder |
14+
| `build/sounds_upgradecode.txt` | **Stable** per-package upgrade-code GUIDs (copied verbatim from freeswitch — do not regenerate, or upgrades break) |
15+
| `gen-version-files.pl` | Generates `build/sounds_version.txt` + `build/moh_version.txt` from `../dist.pl` |
16+
| `docs/COPYING.rtf` | EULA shown by the installer |
17+
| `build-msi.ps1` | Builds a single MSI from a `dist.pl` tarball; used locally and by CI |
18+
19+
`dist.pl` is the single source of truth for versions; the `*_version.txt` files
20+
are generated from it and are git-ignored.
21+
22+
## How it differs from the freeswitch original
23+
24+
The freeswitch project downloaded the sound tarball **and** `7za` from
25+
`files.freeswitch.org` during the MSI build. Here the `EnsureSoundFiles` target
26+
in the wixproj sources the tarball from (in order) an explicit
27+
`/p:SoundTarball=`, `dist.pl`'s local output, or the **GitHub release**, and
28+
extracts it with built-in `tar`. So `msbuild` still works out of the box, with
29+
no `files.freeswitch.org` and no `7za` dependency.
30+
31+
## Building locally
32+
33+
Requires Visual Studio (msbuild), [WiX Toolset v3](https://wixtoolset.org/), and
34+
`curl`/`tar` (built into Windows 10+). `perl` only if you need to regenerate the
35+
version files after editing `dist.pl`.
36+
37+
```powershell
38+
# Convenience wrapper (regenerates version files, builds one MSI from a tarball):
39+
./build-msi.ps1 -Tarball ..\freeswitch-sounds-en-us-callie-48000-1.0.53.tar.gz
40+
```
41+
42+
Or drive `msbuild` directly — the project fetches/extracts the payload itself:
43+
44+
```powershell
45+
# Uses a local tarball if present (dist.pl output in the repo root or .\dist\),
46+
# otherwise downloads it from the GitHub release:
47+
msbuild Setup.Sounds.2017.sln /p:SoundPrimaryName=en-us-callie /p:SoundQuality=8000 /p:Configuration=Release /p:Platform=x64
48+
49+
# Or point it at a specific tarball:
50+
msbuild Setup.Sounds.2017.sln /p:SoundPrimaryName=en-us-callie /p:SoundQuality=8000 /p:SoundTarball=E:\path\freeswitch-sounds-en-us-callie-8000-1.0.53.tar.gz /p:Configuration=Release /p:Platform=x64
51+
52+
# Override the release host (e.g. a fork) with /p:SoundReleaseBaseUrl=...
53+
```
54+
55+
The resulting `FreeSWITCH-Sounds-<voice>-<version>-<rate>Hz.msi` is written to
56+
`windows/x64/`.
57+
58+
## CI
59+
60+
`.github/workflows/build-sounds.yml` builds the tarballs on Linux, then a
61+
Windows job runs `build-msi.ps1` for each tarball and attaches the MSIs to the
62+
same per-package-version GitHub Release as the tarballs.

‎windows/Setup.Sounds.2017.sln‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.25420.1
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup.Sounds.2017", "Setup.Sounds.2017.wixproj", "{4B082D46-C1B0-4DBB-8D8D-AC0D0FDCDBDA}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Release|x64 = Release|x64
11+
EndGlobalSection
12+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
13+
{4B082D46-C1B0-4DBB-8D8D-AC0D0FDCDBDA}.Release|x64.ActiveCfg = Release|x64
14+
{4B082D46-C1B0-4DBB-8D8D-AC0D0FDCDBDA}.Release|x64.Build.0 = Release|x64
15+
EndGlobalSection
16+
GlobalSection(SolutionProperties) = preSolution
17+
HideSolutionNode = FALSE
18+
EndGlobalSection
19+
EndGlobal

0 commit comments

Comments
 (0)