Skip to content

Commit 3eacf2a

Browse files
authored
Merge pull request #276 from Resgrid/develop
Develop
2 parents e4a8de4 + 960f7e3 commit 3eacf2a

33 files changed

Lines changed: 5028 additions & 46 deletions

.github/workflows/dotnet.yml

Lines changed: 137 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,155 @@
1-
# This workflow will build a .NET project
2-
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
1+
# This workflow builds, tests, and releases the Resgrid solution.
2+
# - PRs on any branch: build + test
3+
# - Merged PRs into master: build + test + Docker Hub publish + GitHub Release
34

45
name: .NET
56

67
on:
78
pull_request:
8-
branches: [ "master", "develop" ]
9+
types: [opened, synchronize, reopened]
10+
push:
11+
branches: [ "master" ]
912

10-
jobs:
11-
build:
13+
permissions:
14+
contents: read
15+
16+
env:
17+
DOTNET_VERSION: '9.0.x'
1218

19+
jobs:
20+
# ───────────────────────────────────────────────
21+
# Build & Test – runs on every PR and push to master
22+
# ───────────────────────────────────────────────
23+
build-and-test:
1324
runs-on: ubuntu-latest
1425

1526
steps:
1627
- uses: actions/checkout@v4
28+
1729
- name: Setup .NET
1830
uses: actions/setup-dotnet@v4
1931
with:
20-
dotnet-version: 9.0.x
32+
dotnet-version: ${{ env.DOTNET_VERSION }}
33+
2134
- name: Restore dependencies
2235
run: dotnet restore
36+
2337
- name: Build
24-
run: dotnet build --no-restore
38+
run: dotnet build --no-restore --configuration Release
39+
2540
- name: Test
26-
run: dotnet test --no-build --verbosity normal
41+
run: dotnet test --no-build --configuration Release --verbosity normal
42+
43+
# ───────────────────────────────────────────────
44+
# Docker Build & Push – only on merged PRs to master
45+
# Uses a matrix to build each project's Dockerfile
46+
# ───────────────────────────────────────────────
47+
docker-build-and-push:
48+
needs: build-and-test
49+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
50+
runs-on: ubuntu-latest
51+
52+
strategy:
53+
fail-fast: false
54+
matrix:
55+
include:
56+
- image: resgridllc/resgridwebcore
57+
dockerfile: Web/Resgrid.Web/Dockerfile
58+
- image: resgridllc/resgridwebservices
59+
dockerfile: Web/Resgrid.Web.Services/Dockerfile
60+
- image: resgridllc/resgridwebevents
61+
dockerfile: Web/Resgrid.Web.Eventing/Dockerfile
62+
- image: resgridllc/resgridwebmcp
63+
dockerfile: Web/Resgrid.Web.Mcp/Dockerfile
64+
- image: resgridllc/resgridworkersconsole
65+
dockerfile: Workers/Resgrid.Workers.Console/Dockerfile
66+
67+
steps:
68+
- uses: actions/checkout@v4
69+
70+
- name: Set up Docker Buildx
71+
uses: docker/setup-buildx-action@v3
72+
73+
- name: Login to Docker Hub
74+
uses: docker/login-action@v3
75+
with:
76+
username: ${{ secrets.DOCKERHUB_USERNAME }}
77+
password: ${{ secrets.DOCKERHUB_TOKEN }}
78+
79+
- name: Extract version
80+
id: version
81+
run: |
82+
VERSION="4.${{ github.run_number }}.0"
83+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
84+
85+
- name: Docker meta
86+
id: meta
87+
uses: docker/metadata-action@v5
88+
with:
89+
images: ${{ matrix.image }}
90+
tags: |
91+
type=raw,value=${{ steps.version.outputs.version }}
92+
type=raw,value=latest
93+
type=sha,prefix=
94+
95+
- name: Build and push Docker image
96+
uses: docker/build-push-action@v6
97+
with:
98+
context: .
99+
file: ${{ matrix.dockerfile }}
100+
push: true
101+
build-args: BUILD_VERSION=${{ steps.version.outputs.version }}
102+
tags: ${{ steps.meta.outputs.tags }}
103+
labels: ${{ steps.meta.outputs.labels }}
104+
cache-from: type=gha
105+
cache-to: type=gha,mode=max
106+
107+
# ───────────────────────────────────────────────
108+
# GitHub Release – created after all Docker images are pushed
109+
# Uses the body of the merged PR as release notes
110+
# ───────────────────────────────────────────────
111+
github-release:
112+
needs: docker-build-and-push
113+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
114+
runs-on: ubuntu-latest
115+
116+
permissions:
117+
contents: write
118+
119+
steps:
120+
- uses: actions/checkout@v4
121+
122+
- name: Extract version
123+
id: version
124+
run: |
125+
VERSION="4.${{ github.run_number }}.0"
126+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
127+
128+
- name: Get merged PR info
129+
id: pr-info
130+
uses: actions/github-script@v7
131+
with:
132+
script: |
133+
const prs = await github.rest.repos.listPullRequestsAssociatedWithCommit({
134+
owner: context.repo.owner,
135+
repo: context.repo.repo,
136+
commit_sha: context.sha,
137+
});
138+
const pr = prs.data.find(p => p.merged_at);
139+
const fs = require('fs');
140+
if (pr) {
141+
fs.writeFileSync('release_notes.md', pr.body || 'No release notes provided.');
142+
} else {
143+
fs.writeFileSync('release_notes.md', 'No release notes provided.');
144+
}
145+
146+
- name: Create GitHub Release
147+
uses: softprops/action-gh-release@v2
148+
with:
149+
tag_name: v${{ steps.version.outputs.version }}
150+
name: Release v${{ steps.version.outputs.version }}
151+
body_path: release_notes.md
152+
draft: false
153+
prerelease: false
154+
make_latest: true
155+
fail_on_unmatched_files: false

Core/Resgrid.Services/VoiceService.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@ public VoiceService(IDepartmentVoiceRepository departmentVoiceRepository, IDepar
3838
public async Task<bool> CanDepartmentUseVoiceAsync(int departmentId)
3939
{
4040
var addonPlans = await _subscriptionsService.GetAllAddonPlansByTypeAsync(PlanAddonTypes.PTT);
41-
var addonPayment = await _subscriptionsService.GetCurrentPaymentAddonsForDepartmentAsync(departmentId, addonPlans.Select(x => x.PlanAddonId).ToList());
4241

43-
if (addonPayment != null && addonPayment.Count > 0)
44-
return true;
42+
if (addonPlans != null && addonPlans.Any())
43+
{
44+
var addonPayment = await _subscriptionsService.GetCurrentPaymentAddonsForDepartmentAsync(departmentId, addonPlans.Select(x => x.PlanAddonId).ToList());
45+
46+
if (addonPayment != null && addonPayment.Count > 0)
47+
return true;
48+
}
4549

4650
return false;
4751
}
@@ -61,7 +65,7 @@ public async Task<DepartmentVoice> GetVoiceSettingsForDepartmentAsync(int depart
6165
var voice = await GetOrCreateDepartmentVoiceRecordAsync(department);
6266
var users = await _departmentsService.GetAllUsersForDepartmentAsync(departmentId, true, true);
6367
var userProfiles = await _userProfileService.GetAllProfilesForDepartmentAsync(departmentId, true);
64-
68+
6569
if (users != null && users.Any())
6670
{
6771
foreach (var user in users)
@@ -253,7 +257,7 @@ public async Task<DepartmentVoiceChannel> GetVoiceChannelByIdAsync(string voiceC
253257
}
254258
}
255259
}
256-
260+
257261
return await _departmentVoiceChannelRepository.SaveOrUpdateAsync(voiceChannel, cancellationToken, true);
258262
}
259263

Resgrid.sln

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 17
44
VisualStudioVersion = 17.0.32112.339
@@ -78,6 +78,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Resgrid.Workers.Console", "
7878
EndProject
7979
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Resgrid.Web.Eventing", "Web\Resgrid.Web.Eventing\Resgrid.Web.Eventing.csproj", "{907CA744-0D45-4928-AC26-5724BA6A38EF}"
8080
EndProject
81+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Resgrid.Web.Mcp", "Web\Resgrid.Web.Mcp\Resgrid.Web.Mcp.csproj", "{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}"
82+
EndProject
8183
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Resgrid.Providers.Voip", "Providers\Resgrid.Providers.Voip\Resgrid.Providers.Voip.csproj", "{FFCBA7D4-853A-4D25-935B-F242851752EE}"
8284
EndProject
8385
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Resgrid.Repositories.NoSqlRepository", "Repositories\Resgrid.Repositories.NoSqlRepository\Resgrid.Repositories.NoSqlRepository.csproj", "{086A3F5A-F7D3-4E38-B9CD-B422DD3A709E}"
@@ -706,8 +708,32 @@ Global
706708
{907CA744-0D45-4928-AC26-5724BA6A38EF}.Release|x86.Build.0 = Release|Any CPU
707709
{907CA744-0D45-4928-AC26-5724BA6A38EF}.Staging|Any CPU.ActiveCfg = Release|Any CPU
708710
{907CA744-0D45-4928-AC26-5724BA6A38EF}.Staging|Any CPU.Build.0 = Release|Any CPU
709-
{907CA744-0D45-4928-AC26-5724BA6A38EF}.Staging|x86.ActiveCfg = Release|Any CPU
710-
{907CA744-0D45-4928-AC26-5724BA6A38EF}.Staging|x86.Build.0 = Release|Any CPU
711+
{907CA744-0D45-4928-AC26-5724BA6A38EF}.Staging|x86.ActiveCfg = Debug|Any CPU
712+
{907CA744-0D45-4928-AC26-5724BA6A38EF}.Staging|x86.Build.0 = Debug|Any CPU
713+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Azure|Any CPU.ActiveCfg = Debug|Any CPU
714+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Azure|Any CPU.Build.0 = Debug|Any CPU
715+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Azure|x86.ActiveCfg = Debug|Any CPU
716+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Azure|x86.Build.0 = Debug|Any CPU
717+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Cloud|Any CPU.ActiveCfg = Debug|Any CPU
718+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Cloud|Any CPU.Build.0 = Debug|Any CPU
719+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Cloud|x86.ActiveCfg = Debug|Any CPU
720+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Cloud|x86.Build.0 = Debug|Any CPU
721+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
722+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Debug|Any CPU.Build.0 = Debug|Any CPU
723+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Debug|x86.ActiveCfg = Debug|Any CPU
724+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Debug|x86.Build.0 = Debug|Any CPU
725+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Docker|Any CPU.ActiveCfg = Docker|Any CPU
726+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Docker|Any CPU.Build.0 = Docker|Any CPU
727+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Docker|x86.ActiveCfg = Docker|Any CPU
728+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Docker|x86.Build.0 = Docker|Any CPU
729+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Release|Any CPU.ActiveCfg = Release|Any CPU
730+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Release|Any CPU.Build.0 = Release|Any CPU
731+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Release|x86.ActiveCfg = Release|Any CPU
732+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Release|x86.Build.0 = Release|Any CPU
733+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Staging|Any CPU.ActiveCfg = Debug|Any CPU
734+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Staging|Any CPU.Build.0 = Debug|Any CPU
735+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Staging|x86.ActiveCfg = Debug|Any CPU
736+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678}.Staging|x86.Build.0 = Debug|Any CPU
711737
{FFCBA7D4-853A-4D25-935B-F242851752EE}.Azure|Any CPU.ActiveCfg = Debug|Any CPU
712738
{FFCBA7D4-853A-4D25-935B-F242851752EE}.Azure|Any CPU.Build.0 = Debug|Any CPU
713739
{FFCBA7D4-853A-4D25-935B-F242851752EE}.Azure|x86.ActiveCfg = Debug|Any CPU
@@ -882,6 +908,7 @@ Global
882908
{C89A962F-75AC-4D0B-9B8A-B481F63810EC} = {DBB9862A-C008-4C3F-A9DB-320429E4A07F}
883909
{477AAB02-9403-44BE-B912-3DA98660F307} = {DBB9862A-C008-4C3F-A9DB-320429E4A07F}
884910
{907CA744-0D45-4928-AC26-5724BA6A38EF} = {53B024F9-E293-42F1-BA67-7F68C3F3C243}
911+
{A8B9C1D2-E3F4-5678-9ABC-DEF012345678} = {53B024F9-E293-42F1-BA67-7F68C3F3C243}
885912
{FFCBA7D4-853A-4D25-935B-F242851752EE} = {F06D475C-635C-4DE4-82BA-C49A90BA8FCD}
886913
{086A3F5A-F7D3-4E38-B9CD-B422DD3A709E} = {206D5D48-99B0-4913-B1E2-4BA11D021740}
887914
{E39D63BA-5CCA-43EC-A3F9-375FA87EFE2F} = {D43D1D6B-66A9-4A57-9EA3-8DECC92FA583}

Web/Resgrid.Web.Mcp/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
bin/
2+
obj/
3+
*.user
4+
*.suo
5+
.vs/
6+

0 commit comments

Comments
 (0)