Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions .github/workflows/build-test-installer-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: Build Test Installer Release

on:
pull_request:
branches:
- main
push:
branches:
- main
tags:
- 'v*'
workflow_dispatch:

permissions:
contents: write
id-token: write
actions: read
checks: write

env:
Configuration: Release

jobs:
build_test:
name: Build Test Installer Release
runs-on: windows-latest
outputs:
version: ${{ steps.compute_version.outputs.version }}

steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-tags: true
fetch-depth: 0
submodules: true

- name: Compute Version
id: compute_version
#working-directory: ${{ github.workspace }}
shell: bash
run: |
git describe --tags --match "v*" --abbrev=0 || echo "No existing tag found"
# If this is a tag push and it starts with v, just use it and strip off the v
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
Version="${GITHUB_REF#refs/tags/}"
Version="${Version#v}"
echo "version=$Version" >> $GITHUB_OUTPUT
echo "detected tag push: $Version"
exit 0
fi

# Otherwise find the latest tag that starts with v
LAST_TAG=$(git describe --tags --match "v*" --abbrev=0 2>/dev/null || echo "v0.0.0")

# Compute a build number based on number of commits since that tag
COMMITS_SINCE_TAG=$(git rev-list ${LAST_TAG}..HEAD --count)

# Final version: X.Y.Z (stripped off the v)
Version="${LAST_TAG#v}.${COMMITS_SINCE_TAG}"
echo "version=$Version" >> $GITHUB_OUTPUT
echo "no tag push; using $Version"

- name: Setup NuGet
uses: NuGet/setup-nuget@v2

- name: Restore NuGet packages
run: nuget restore SayMore.sln

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
with:
vs-version: '[17.0,18.0)'

- name: Build
run: msbuild build\SayMore.proj /t:Build /p:Configuration=$env:Configuration /p:Version=$env:Version /m

- name: Run Tests
run: msbuild build\SayMore.proj /t:Test /p:Configuration=$env:Configuration /p:useNUnit-x86=true /p:excludedCategories=SkipOnCI /m

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: saymore-test-results
if-no-files-found: warn
path: output/${{ env.Configuration }}/TestResults.xml

- name: Copy CHM file into DistFiles
run: copy "docs\SayMore.chm" "DistFiles\SayMore.chm"

- name: Create HTML release notes
run: msbuild build\SayMore.proj /t:ConvertReleaseNotesToHtml /p:Version=$env:Version /m

- name: Build installer
if: ${{ github.event_name != 'pull_request' }}
run: msbuild build\SayMore.proj /t:Installer /p:Configuration=$env:Configuration /p:Version=$env:Version /m

- name: Sign installer
if: ${{ github.event_name != 'pull_request' }}
uses: sillsdev/codesign/trusted-signing-action@v3
with:
credentials: ${{ secrets.TRUSTED_SIGNING_CREDENTIALS }}
files-folder: output/installer
files-folder-filter: SayMoreInstaller*.msi

- name: Upload installer artifacts
if: ${{ github.event_name != 'pull_request' }}
uses: actions/upload-artifact@v4
with:
name: saymore-installer
if-no-files-found: error
path: |
output/installer/SayMoreInstaller*.msi
output/installer/*.download_info
output/installer/appcast.xml
output/releasenotes.download_info
output/ReleaseNotes.htm

- name: Create release
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
uses: softprops/action-gh-release@v2
with:
files: |
output/installer/SayMoreInstaller*.msi
output/installer/*.download_info
output/installer/appcast.xml
output/releasenotes.download_info
output/ReleaseNotes.htm
draft: true
generate_release_notes: true
report:
name: Test Report
needs: build_test
runs-on: ubuntu-latest
steps:
- uses: dorny/test-reporter@v2
with:
artifact: saymore-test-results
name: NUnit Tests
path: '*.xml'
reporter: dotnet-nunit
22 changes: 22 additions & 0 deletions .github/workflows/test-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: 'Test Report'
# This is recommended to run after the CI workflow to publish test results since it has different
# permissions
on:
workflow_run:
workflows: ['CI'] # runs after CI workflow
types:
- completed
permissions:
contents: read
actions: read
checks: write
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: dorny/test-reporter@v2
with:
artifact: saymore-test-results
name: NUnit Tests
path: '*.xml' # Path to test results (inside artifact .zip)
reporter: dotnet-nunit
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "docs"]
path = docs
url = https://github.com/sillsdev/saymore-doc.git
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SayMore�
# SayMore�

SayMore provides an intuitive and enjoyable way to manage language documentation tasks.

Expand All @@ -22,6 +22,14 @@ Please see [Tips for Testing Palaso Software](https://docs.google.com/document/d

Reports can be entered in https://jira.sil.org/projects/SP/issues. They can be entered there via email by sending to [email protected].

### Continuous Build System
## Github Actions CI
Every PR triggers a build and runs tests.

Each time code is checked in, an automatic build begins on our [TeamCity build server](https://build.palaso.org/project.html?projectId=SayMore&tab=projectOverview), running all the unit tests. This automatic build doesn't publish a new installer, however. That kind of build is launched manually, by pressing a button on the TeamCity page. This "publish" process builds SayMore, makes and installer, rsyncs it to the distribution server, and writes out a little bit of html which the [SayMore download page](https://software.sil.org/saymore/download/) then displays to the user. It also creates a build artifact that enables the SayMore program to check to see whether a newer version is available.
Every commit on the main branch will produce a signed installer for user testing as desired. Simply go to the Actions tab and find the Actions run for that commit if you want to download the installer. The installer is attached to the run artifact.

# Release Process
To release a new version, just tag a commit on the main branch e.g. v3.7.5
This will trigger Github Actions to produce a Release with the signed installer attached

# Release TODO
Implement the "publish" process on TeamCity, which builds SayMore, makes and installer, rsyncs it to the distribution server, and writes out a little bit of html which the [SayMore download page](https://software.sil.org/saymore/download/) then displays to the user. It also creates a build artifact that enables the SayMore program to check to see whether a newer version is available.
98 changes: 37 additions & 61 deletions build/SayMore.proj
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<RootDir Condition="'$(teamcity_version)' == ''">$(MSBuildProjectDirectory)\..</RootDir>
<RootDir Condition="'$(teamcity_version)' != ''">$(teamcity_build_checkoutDir)</RootDir>
<BUILD_NUMBER Condition="'$(BUILD_NUMBER)'==''">3.7.100</BUILD_NUMBER>
<RootDir>$(MSBuildProjectDirectory)\..</RootDir>
<RootDir Condition="'$(GITHUB_WORKSPACE)' != ''">$(GITHUB_WORKSPACE)</RootDir>
<BuildTasksDll Condition="Exists('$(RootDir)/packages/SIL.BuildTasks.3.1.1/tools/SIL.BuildTasks.dll')">$(RootDir)/packages/SIL.BuildTasks.3.1.1/tools/SIL.BuildTasks.dll</BuildTasksDll>
<BuildTasksDll Condition="!Exists('$(RootDir)/packages/SIL.BuildTasks.3.1.1/tools/SIL.BuildTasks.dll')">$(RootDir)/packages/SIL.BuildTasks/tools/SIL.BuildTasks.dll</BuildTasksDll>
<SILReleaseTasksProps>$(RootDir)/packages/SIL.ReleaseTasks.3.1.1/build/SIL.ReleaseTasks.props</SILReleaseTasksProps>
Expand All @@ -20,7 +19,6 @@
<Exec Command='$(NuGetCommand) install SIL.BuildTasks -excludeVersion -PreRelease -source "$(PackageSources)" -solutionDirectory "$(SolutionDir)."' />
<Exec Command='$(NuGetCommand) install SIL.ReleaseTasks -excludeVersion -PreRelease -source "$(PackageSources)" -solutionDirectory "$(SolutionDir)"' />
<Exec Command='$(NuGetCommand) install SIL.libpalaso.l10ns -excludeVersion -PreRelease -source "$(PackageSources)" -solutionDirectory "$(SolutionDir)."' />
<Exec Command='$(NuGetCommand) install NUnit.Extension.TeamCityEventListener -excludeVersion -source "$(PackageSources)" -solutionDirectory "$(SolutionDir)."' />
<MSBuild Projects="$(MSBuildProjectFullPath)" Targets="BuildInternal"
Properties="Configuration=$(Configuration)" Condition="$(RestartBuild)" />
</Target>
Expand All @@ -33,18 +31,10 @@
<UsingTask TaskName="NUnit3" AssemblyFile="$(BuildTasksDll)" Condition="Exists('$(BuildTasksDll)')" />

<Target Name="VersionNumbers">
<Message Text="BUILD_NUMBER: $(BUILD_NUMBER)" Importance="high"/>

<Split Input="$(BUILD_NUMBER)" Delimiter="." OutputSubString="2">
<Output TaskParameter="ReturnValue" PropertyName="BuildCounter" />
</Split>

<Message Text="BuildCounter: $(BuildCounter)" Importance="high"/>

<!-- Note, after some thought, we've decided this is the best place to keep the version number (not on TeamCity, not in the assemblies). -->
<CreateProperty Value="3.7.$(BuildCounter)">
<Output PropertyName="Version" TaskParameter="Value"/>
</CreateProperty>
<PropertyGroup>
<!-- The Version should be set from the outside, if not, set a meaningless default value -->
<Version Condition="'$(Version)' == ''">1.0.0.0</Version>
</PropertyGroup>

<Message Text="Version: $(Version)" Importance="high"/>
</Target>
Expand Down Expand Up @@ -84,7 +74,7 @@
<ItemGroup>
<TestAssemblies Include="$(RootDir)/output/release/*Tests.dll;"/>
</ItemGroup>
<NUnit3 Condition="'$(teamcity_version)' == ''"
<NUnit3
Assemblies="@(TestAssemblies)"
ToolPath="$(RootDir)/packages/NUnit.ConsoleRunner.3.20.1/tools"
ExcludeCategory="$(excludedCategories)"
Expand All @@ -94,15 +84,7 @@
OutputXmlFile="$(RootDir)/output/$(Configuration)/TestResults.xml"
UseNUnit3Xml = "true"
TeamCity="false"/>
<NUnit3 Condition="'$(teamcity_version)' != ''"
Assemblies="@(TestAssemblies)"
ToolPath="$(RootDir)/packages/NUnit.ConsoleRunner.3.20.1/tools"
ExcludeCategory="SkipOnTeamCity,$(excludedCategories)"
WorkingDirectory="$(RootDir)/output/$(Configuration)"
Force32Bit="$(useNUnit-x86)"
Verbose="true"
TeamCity="true"/>
</Target>
</Target>

<Target Name="UpdateDownloadInfo" DependsOnTargets="VersionNumbers" >

Expand Down Expand Up @@ -149,21 +131,34 @@
changing of the script, but I haven't figured that out. -->

<FileUpdate File="$(RootDir)\src\Installer\Installer.wxs" Regex='Property_ProductVersion = ".*"'
ReplacementText ="Property_ProductVersion = &quot;$(Version)&quot;" />
ReplacementText ="Property_ProductVersion = &quot;$(Version)&quot;" />

<Message Text="Making Installer Version: $(Version)" Importance="high" />

<MSBuild Projects="$(RootDir)\src\Installer\Installer.wixproj"/>

<!-- remove an existing one with the same name, if necessary -->
<Delete Files="$(RootDir)\output\installer\SayMoreInstaller.$(Version).msi" TreatErrorsAsWarnings="false" />
<!-- Ensure destination folder exists -->
<MakeDir Directories="$(RootDir)\output\installer" />

<Exec Command='sign /d "SayMoreInstaller.$(Version).msi" "$(RootDir)\output\installer\SayMoreInstaller.msi"'></Exec>
<PropertyGroup>
<InstallerSourceMsi>$(RootDir)\output\installer\SayMoreInstaller.msi</InstallerSourceMsi>
<InstallerSourceMsi Condition="!Exists('$(InstallerSourceMsi)')">$(RootDir)\src\Installer\bin\$(Configuration)\SayMoreInstaller.msi</InstallerSourceMsi>
<InstallerSourceMsi Condition="!Exists('$(InstallerSourceMsi)')">$(RootDir)\src\Installer\bin\$(Configuration)\en-us\SayMoreInstaller.msi</InstallerSourceMsi>
</PropertyGroup>

<Copy SourceFiles="$(RootDir)\output\installer\SayMoreInstaller.msi"
DestinationFiles="$(RootDir)\output\installer\SayMoreInstaller.$(Version).msi"
/>

<!-- Helpful debug -->
<Message Text="Looking for MSI at: $(InstallerSourceMsi)" Importance="high" />

<!-- Guard with an explicit error if it's missing -->
<Error
Text="Expected MSI not found at $(InstallerSourceMsi)."
Condition="!Exists('$(InstallerSourceMsi)')" />

<!-- Copy + rename with version -->
<Copy
SourceFiles="$(InstallerSourceMsi)"
DestinationFiles="$(RootDir)\output\installer\SayMoreInstaller.$(Version).msi" />

<!-- appcast.xml is used as part of the update notification system -->
<Copy SourceFiles ="$(RootDir)\src\Installer\appcast.xml"
DestinationFolder ="$(RootDir)\output\installer"/>
Expand All @@ -177,46 +172,27 @@

</Target>

<!-- The "Installer" Target used to depend on this, but the Edolo Sample data was removed
in version 3 of SayMore, so there is no need to continue to generate this WIX include
file. (See SampleData\ReadMe.txt)
<Target Name="MakeWixForSampleData">
<MakeDir ContinueOnError ="true" Directories ="$(RootDir)\output\Installer\"/>

<MakeWixForDirTree
DirectoryReferenceId="SampleDataDir"
GiveAllPermissions="true"
ComponentGroupId="SampleData"
RootDirectory="$(RootDir)\SampleData"
OutputFilePath="$(RootDir)\output\Installer\GeneratedSampleDataFiles.wxs"
MatchRegExPattern=".*"
>
<Output TaskParameter="OutputFilePath" ItemName="Compile" />
</MakeWixForDirTree>
</Target>
-->

<Target Name="copyLibL10ns" DependsOnTargets="RestoreLocalPackages">
<Error Text="Palaso L10ns package missing. Expected at $(RootDir)/packages/SIL.libpalaso.l10ns"
Condition="!Exists('$(RootDir)/packages/SIL.libpalaso.l10ns/SIL.libpalaso.l10ns.nupkg')" />
<ItemGroup>
<XliffFiles Include="$(RootDir)/packages/SIL.libpalaso.l10ns/content/**/*.xlf"/>
</ItemGroup>
<Copy SourceFiles="@(XliffFiles)"
DestinationFiles="@(XliffFiles->'$(RootDir)/DistFiles/%(Filename)%(Extension)')"
SkipUnchangedFiles="true"/>
DestinationFiles="@(XliffFiles->'$(RootDir)/DistFiles/%(Filename)%(Extension)')"
SkipUnchangedFiles="true"/>
</Target>

<Target Name="MakeWixForDistFiles" DependsOnTargets="copyLibL10ns">
<MakeDir ContinueOnError ="true" Directories ="$(RootDir)\output\Installer\"/>

<MakeWixForDirTree
DirectoryReferenceId="ProgramDir"
ComponentGroupId="DistFiles"
RootDirectory="$(RootDir)\DistFiles"
OutputFilePath="$(RootDir)\output\Installer\GeneratedDistFiles.wxs"
MatchRegExPattern=".*"
>
DirectoryReferenceId="ProgramDir"
ComponentGroupId="DistFiles"
RootDirectory="$(RootDir)\DistFiles"
OutputFilePath="$(RootDir)\output\Installer\GeneratedDistFiles.wxs"
MatchRegExPattern=".*"
>
<!--what does this do?-->
<Output TaskParameter="OutputFilePath" ItemName="Compile" />
</MakeWixForDirTree>
Expand Down
1 change: 1 addition & 0 deletions docs
Submodule docs added at 68cafb
Loading