Skip to content

Commit 3fdff9e

Browse files
committed
Add github actions workflow, remove AppVeyor
1 parent 4e97f5c commit 3fdff9e

7 files changed

Lines changed: 361 additions & 63 deletions

File tree

.github/workflows/build.yml

Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
name: CI/CD
2+
3+
on:
4+
push:
5+
branches:
6+
- '**'
7+
8+
permissions:
9+
contents: write
10+
11+
# Cancel any in-progress run on the same branch
12+
concurrency:
13+
group: ${{ github.workflow }}-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
env:
17+
DOTNET_NOLOGO: true
18+
DOTNET_CLI_TELEMETRY_OPTOUT: true
19+
20+
jobs:
21+
# ============================================================
22+
# BUILD — runs on every branch push
23+
# ============================================================
24+
build:
25+
name: Build
26+
runs-on: windows-latest
27+
28+
outputs:
29+
version: ${{ steps.version.outputs.semver }}
30+
zip_prefix: ${{ steps.version.outputs.zip_prefix }}
31+
32+
steps:
33+
- name: Checkout
34+
uses: actions/checkout@v4
35+
with:
36+
fetch-depth: 0 # GitVersion needs full history
37+
38+
# ── Version calculation (master only) ───────────────────────────────────
39+
40+
- name: Install GitVersion
41+
if: github.ref == 'refs/heads/master'
42+
uses: gittools/actions/gitversion/setup@v3.0.0
43+
with:
44+
versionSpec: '5.x'
45+
46+
- name: Execute GitVersion
47+
if: github.ref == 'refs/heads/master'
48+
id: gitversion
49+
uses: gittools/actions/gitversion/execute@v3.0.0
50+
51+
- name: Set build version
52+
id: version
53+
shell: bash
54+
run: |
55+
if [ "$GITHUB_REF" = "refs/heads/master" ]; then
56+
SEMVER="${{ steps.gitversion.outputs.semVer }}"
57+
ASSEMBLY_VER="${{ steps.gitversion.outputs.assemblySemVer }}"
58+
else
59+
SEMVER=""
60+
ASSEMBLY_VER=""
61+
fi
62+
ZIP_PREFIX="MenuAPI-${SEMVER:-dev-${{ github.run_number }}}"
63+
echo "semver=$SEMVER" >> "$GITHUB_OUTPUT"
64+
echo "assembly_ver=$ASSEMBLY_VER" >> "$GITHUB_OUTPUT"
65+
echo "zip_prefix=$ZIP_PREFIX" >> "$GITHUB_OUTPUT"
66+
67+
# ── Restore ─────────────────────────────────────────────────────────────
68+
69+
- name: Restore NuGet packages
70+
run: dotnet restore MenuAPI.sln
71+
72+
# ── Build FiveM ──────────────────────────────────────────────────────────
73+
74+
- name: Build FiveM (versioned)
75+
if: github.ref == 'refs/heads/master'
76+
shell: bash
77+
run: |
78+
dotnet build MenuAPI/MenuAPI.csproj -c "Release FiveM" --no-restore \
79+
/p:Version=${{ steps.version.outputs.semver }} \
80+
/p:AssemblyVersion=${{ steps.version.outputs.assembly_ver }} \
81+
/p:FileVersion=${{ steps.version.outputs.assembly_ver }}
82+
83+
- name: Build FiveM
84+
if: github.ref != 'refs/heads/master'
85+
run: dotnet build MenuAPI/MenuAPI.csproj -c "Release FiveM" --no-restore
86+
87+
# ── Build RedM ───────────────────────────────────────────────────────────
88+
89+
- name: Build RedM (versioned)
90+
if: github.ref == 'refs/heads/master'
91+
shell: bash
92+
run: |
93+
dotnet build MenuAPI/MenuAPI.csproj -c "Release RedM" --no-restore \
94+
/p:Version=${{ steps.version.outputs.semver }} \
95+
/p:AssemblyVersion=${{ steps.version.outputs.assembly_ver }} \
96+
/p:FileVersion=${{ steps.version.outputs.assembly_ver }}
97+
98+
- name: Build RedM
99+
if: github.ref != 'refs/heads/master'
100+
run: dotnet build MenuAPI/MenuAPI.csproj -c "Release RedM" --no-restore
101+
102+
# ── Package zip artifacts ────────────────────────────────────────────────
103+
104+
- name: Package FiveM zip
105+
shell: pwsh
106+
run: |
107+
$outDir = 'MenuAPI/bin/Release FiveM/net452'
108+
Copy-Item README.md "$outDir/README.md" -Force
109+
Compress-Archive -Path "$outDir/*" -DestinationPath "${{ steps.version.outputs.zip_prefix }}-FiveM.zip" -Force
110+
111+
- name: Package RedM zip
112+
shell: pwsh
113+
run: |
114+
$outDir = 'MenuAPI/bin/Release RedM/net452'
115+
Copy-Item README.md "$outDir/README.md" -Force
116+
Compress-Archive -Path "$outDir/*" -DestinationPath "${{ steps.version.outputs.zip_prefix }}-RedM.zip" -Force
117+
118+
- name: Upload FiveM zip
119+
uses: actions/upload-artifact@v4
120+
with:
121+
name: zip-fivem
122+
path: ${{ steps.version.outputs.zip_prefix }}-FiveM.zip
123+
124+
- name: Upload RedM zip
125+
uses: actions/upload-artifact@v4
126+
with:
127+
name: zip-redm
128+
path: ${{ steps.version.outputs.zip_prefix }}-RedM.zip
129+
130+
# ── NuGet packaging (master only) ────────────────────────────────────────
131+
132+
- name: Pack NuGet FiveM
133+
if: github.ref == 'refs/heads/master'
134+
run: >-
135+
dotnet pack MenuAPI/MenuAPI.csproj
136+
-c "Release FiveM"
137+
--no-restore
138+
/p:PackageVersion=${{ steps.version.outputs.semver }}
139+
/p:DefineConstants=FIVEM
140+
/p:PackageId=MenuAPI.FiveM
141+
-o nupkgs
142+
143+
- name: Pack NuGet RedM
144+
if: github.ref == 'refs/heads/master'
145+
run: >-
146+
dotnet pack MenuAPI/MenuAPI.csproj
147+
-c "Release RedM"
148+
--no-restore
149+
/p:PackageVersion=${{ steps.version.outputs.semver }}
150+
/p:DefineConstants=REDM
151+
/p:PackageId=MenuAPI.RedM
152+
-o nupkgs
153+
154+
- name: Upload NuGet packages
155+
if: github.ref == 'refs/heads/master'
156+
uses: actions/upload-artifact@v4
157+
with:
158+
name: nuget-packages
159+
path: nupkgs/*.nupkg
160+
161+
# ============================================================
162+
# RELEASE — master only, after successful build
163+
# ============================================================
164+
release:
165+
name: Release
166+
needs: build
167+
if: github.ref == 'refs/heads/master'
168+
runs-on: windows-latest
169+
170+
outputs:
171+
release_url: ${{ steps.create_release.outputs.release_url }}
172+
173+
steps:
174+
- name: Checkout
175+
uses: actions/checkout@v4
176+
with:
177+
fetch-depth: 0
178+
179+
- name: Download FiveM zip
180+
uses: actions/download-artifact@v4
181+
with:
182+
name: zip-fivem
183+
path: release-assets
184+
185+
- name: Download RedM zip
186+
uses: actions/download-artifact@v4
187+
with:
188+
name: zip-redm
189+
path: release-assets
190+
191+
- name: Download NuGet packages
192+
uses: actions/download-artifact@v4
193+
with:
194+
name: nuget-packages
195+
path: release-assets
196+
197+
# Generate changelog BEFORE tagging so the tag range is correct
198+
- name: Generate changelog
199+
shell: bash
200+
run: |
201+
LAST_TAG=$(git tag --sort=-version:refname | head -n 1)
202+
if [ -n "$LAST_TAG" ]; then
203+
git log "$LAST_TAG..HEAD" --pretty=format:"- %s" --no-merges > changelog.txt
204+
else
205+
git log --pretty=format:"- %s" --no-merges > changelog.txt
206+
fi
207+
echo "Last tag used for changelog: ${LAST_TAG:-<none, full history>}"
208+
cat changelog.txt
209+
210+
- name: Create and push git tag
211+
shell: bash
212+
run: |
213+
VERSION="${{ needs.build.outputs.version }}"
214+
git config user.name "github-actions[bot]"
215+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
216+
git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}"
217+
git tag "v$VERSION"
218+
git push origin "v$VERSION"
219+
220+
- name: Create GitHub Release
221+
id: create_release
222+
shell: bash
223+
env:
224+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
225+
run: |
226+
VERSION="${{ needs.build.outputs.version }}"
227+
{
228+
echo "MenuAPI release v${VERSION}. Download the **FiveM** or **RedM** versions below."
229+
echo ""
230+
echo "## Changes"
231+
cat changelog.txt
232+
echo ""
233+
echo "For more info, check the [docs](https://docs.vespura.com/mapi)."
234+
} > release_notes.md
235+
236+
RELEASE_URL=$(gh release create "v$VERSION" \
237+
--title "MenuAPI v$VERSION" \
238+
--notes-file release_notes.md \
239+
"release-assets/MenuAPI-$VERSION-FiveM.zip" \
240+
"release-assets/MenuAPI-$VERSION-RedM.zip")
241+
242+
echo "release_url=$RELEASE_URL" >> "$GITHUB_OUTPUT"
243+
244+
- name: Publish NuGet — FiveM
245+
run: >-
246+
dotnet nuget push
247+
"release-assets/MenuAPI.FiveM.${{ needs.build.outputs.version }}.nupkg"
248+
--api-key ${{ secrets.NUGET_API_KEY }}
249+
--source https://api.nuget.org/v3/index.json
250+
--skip-duplicate
251+
252+
- name: Publish NuGet — RedM
253+
run: >-
254+
dotnet nuget push
255+
"release-assets/MenuAPI.RedM.${{ needs.build.outputs.version }}.nupkg"
256+
--api-key ${{ secrets.NUGET_API_KEY }}
257+
--source https://api.nuget.org/v3/index.json
258+
--skip-duplicate
259+
260+
# ============================================================
261+
# DISCORD NOTIFICATION — always runs
262+
# ============================================================
263+
notify:
264+
name: Discord Notification
265+
needs: [build, release]
266+
if: always()
267+
runs-on: ubuntu-latest
268+
269+
steps:
270+
- name: Send Discord notification
271+
shell: bash
272+
env:
273+
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
274+
run: |
275+
if [ -z "$DISCORD_WEBHOOK_URL" ]; then
276+
echo "DISCORD_WEBHOOK_URL not configured, skipping."
277+
exit 0
278+
fi
279+
280+
BUILD_RESULT="${{ needs.build.result }}"
281+
RELEASE_RESULT="${{ needs.release.result }}"
282+
VERSION="${{ needs.build.outputs.version }}"
283+
284+
# ── Status colour & label ──────────────────────────────────────────
285+
if [ "$BUILD_RESULT" = "cancelled" ] || [ "$RELEASE_RESULT" = "cancelled" ]; then
286+
COLOR=16776960 # yellow
287+
STATUS_TEXT="Build cancelled."
288+
elif [ "$BUILD_RESULT" = "success" ] && \
289+
{ [ "$RELEASE_RESULT" = "success" ] || [ "$RELEASE_RESULT" = "skipped" ]; }; then
290+
COLOR=4502298 # green
291+
STATUS_TEXT="Build passed!"
292+
else
293+
COLOR=13632027 # red
294+
STATUS_TEXT="Build FAILED!"
295+
fi
296+
297+
# ── Link field ─────────────────────────────────────────────────────
298+
RELEASE_URL="${{ needs.release.outputs.release_url }}"
299+
if [ -n "$RELEASE_URL" ] && [ "$RELEASE_RESULT" = "success" ]; then
300+
LINK_NAME="GitHub Release"
301+
LINK_URL="$RELEASE_URL"
302+
else
303+
LINK_NAME="Build Run"
304+
LINK_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
305+
fi
306+
307+
# ── Version label ──────────────────────────────────────────────────
308+
DISPLAY_VERSION="${VERSION:-dev-${{ github.run_number }}}"
309+
SHA="${{ github.sha }}"
310+
SHORT_SHA="${SHA:0:7}"
311+
312+
# ── Build JSON safely via jq ───────────────────────────────────────
313+
PAYLOAD=$(jq -n \
314+
--arg title "MenuAPI (v${DISPLAY_VERSION})" \
315+
--arg desc "$STATUS_TEXT" \
316+
--argjson color "$COLOR" \
317+
--arg actor "${{ github.actor }}" \
318+
--arg actor_url "https://github.com/${{ github.actor }}" \
319+
--arg branch "${{ github.ref_name }}" \
320+
--arg link_name "$LINK_NAME" \
321+
--arg link_url "$LINK_URL" \
322+
--arg short_sha "$SHORT_SHA" \
323+
--arg commit_url "https://github.com/${{ github.repository }}/commit/${{ github.sha }}" \
324+
--arg commit_msg "${{ github.event.head_commit.message }}" \
325+
'{
326+
embeds: [{
327+
title: $title,
328+
description: $desc,
329+
color: $color,
330+
author: {
331+
name: ("Committed by " + $actor),
332+
url: $actor_url
333+
},
334+
fields: [
335+
{ name: "Branch", value: $branch, inline: true },
336+
{ name: $link_name, value: ("[Link](" + $link_url + ")"), inline: true },
337+
{ name: "Commit", value: ("[`" + $short_sha + "`](" + $commit_url + ") — " + $commit_msg), inline: false }
338+
]
339+
}]
340+
}')
341+
342+
curl -fsSL -H "Content-Type: application/json" -X POST -d "$PAYLOAD" "$DISCORD_WEBHOOK_URL"

GitVersion.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# GitVersion configuration
2+
# Docs: https://gitversion.net/docs/reference/configuration
3+
#
4+
# Mode: Mainline — every commit to master auto-increments the patch version.
5+
# Override the increment for a specific commit by including one of these
6+
# anywhere in the commit message:
7+
# +semver: major → bumps major (e.g. 1.2.3 → 2.0.0)
8+
# +semver: minor → bumps minor (e.g. 1.2.3 → 1.3.0)
9+
# +semver: patch → bumps patch (e.g. 1.2.3 → 1.2.4) ← default
10+
# +semver: none → no bump on this commit
11+
12+
assembly-versioning-scheme: MajorMinorPatch
13+
assembly-file-versioning-scheme: MajorMinorPatch
14+
mode: Mainline
15+
16+
# Starting version — update this if you already have tagged releases and want
17+
# GitVersion to resume from a specific baseline instead.
18+
next-version: 1.0.0

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
**FiveM & RedM C# Menu API**
44

5-
[![Discord](https://discordapp.com/api/guilds/285424882534187008/widget.png)](https://vespura.com/discord) [![CodeFactor](https://www.codefactor.io/repository/github/tomgrobbe/menuapi/badge)](https://www.codefactor.io/repository/github/tomgrobbe/menuapi) [![Build status](https://ci.appveyor.com/api/projects/status/8nqoeyg0e9rn10ih/branch/master?svg=true)](https://ci.appveyor.com/project/TomGrobbe/menuapi/branch/master) [![Patreon](https://img.shields.io/badge/donate-Patreon-orange.svg)](https://www.patreon.com/vespura)
5+
[![Discord](https://discordapp.com/api/guilds/285424882534187008/widget.png)](https://vespura.com/discord) [![CodeFactor](https://www.codefactor.io/repository/github/tomgrobbe/menuapi/badge)](https://www.codefactor.io/repository/github/tomgrobbe/menuapi) [![Patreon](https://img.shields.io/badge/donate-Patreon-orange.svg)](https://www.patreon.com/vespura)
66

77
Designed specifically as a replacement of **NativeUI**, MenuAPI features performance improvements, **RedM** _and_ **FiveM** support, improved stability, better features, less bugs, full safezone alignment support for both left and right algined menus (FiveM only) and less (in my opinion) unnecessary features.
88

0 commit comments

Comments
 (0)