summaryrefslogtreecommitdiff
path: root/.github
diff options
context:
space:
mode:
Diffstat (limited to '.github')
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.yml65
-rw-r--r--.github/ISSUE_TEMPLATE/config.yml5
-rw-r--r--.github/ISSUE_TEMPLATE/rfc.yml68
-rw-r--r--.github/ISSUE_TEMPLATE/suggestion.yml38
-rw-r--r--.github/actions/meshmc/package/linux/action.yml153
-rw-r--r--.github/actions/meshmc/package/macos/action.yml146
-rw-r--r--.github/actions/meshmc/package/windows/action.yml142
-rw-r--r--.github/actions/meshmc/setup-dependencies/action.yml89
-rw-r--r--.github/actions/meshmc/setup-dependencies/linux/action.yml59
-rw-r--r--.github/actions/meshmc/setup-dependencies/macos/action.yml52
-rw-r--r--.github/actions/meshmc/setup-dependencies/windows/action.yml114
-rw-r--r--.github/actions/uvim/test_artifacts/action.yml55
-rw-r--r--.github/codeql/codeql-config.yml3
-rw-r--r--.github/dco.yml2
-rw-r--r--.github/pull_request_template.md9
-rw-r--r--.github/workflows/cgit-ci.yml60
-rw-r--r--.github/workflows/cmark-ci.yml129
-rw-r--r--.github/workflows/cmark-fuzz.yml30
-rw-r--r--.github/workflows/corebinutils-ci.yml69
-rw-r--r--.github/workflows/forgewrapper-build.yml62
-rw-r--r--.github/workflows/genqrcode-ci.yml71
-rw-r--r--.github/workflows/images4docker-build.yml85
-rw-r--r--.github/workflows/json4cpp-ci.yml166
-rw-r--r--.github/workflows/meshmc-backport.yml28
-rw-r--r--.github/workflows/meshmc-blocked-prs.yml257
-rw-r--r--.github/workflows/meshmc-build.yml190
-rw-r--r--.github/workflows/meshmc-codeql.yml59
-rw-r--r--.github/workflows/meshmc-container.yml178
-rw-r--r--.github/workflows/meshmc-flake-update.yml39
-rw-r--r--.github/workflows/meshmc-merge-blocking-pr.yml64
-rw-r--r--.github/workflows/meshmc-nix.yml122
-rw-r--r--.github/workflows/meshmc-publish.yml25
-rw-r--r--.github/workflows/meshmc-release.yml124
-rw-r--r--.github/workflows/tomlplusplus-ci.yml146
-rw-r--r--.github/workflows/uvim-ci.yml180
35 files changed, 3084 insertions, 0 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000000..3c147eb94b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,65 @@
+name: Bug Report
+description: File a bug report
+labels: [bug, needs-triage]
+body:
+- type: markdown
+ attributes:
+ value: |
+ If you need help with running Minecraft, please visit us [on our Discord](https://discord.gg/meshmc) before making a bug report.
+
+ Before submitting a bug report, please make sure you have read this *entire* form, and that:
+ * You have read the [FAQ](https://github.com/Project-Tick/MeshMC/wiki/FAQ) and it has not answered your question
+ * Your bug is not caused by Minecraft or any mods you have installed.
+ * Your issue has not been reported before, [make sure to use the search function!](https://github.com/Project-Tick/MeshMC/issues)
+
+ **Do not forget to give your issue a descriptive title.** "Bug in the instance screen" makes it hard to distinguish issues at a glance.
+- type: dropdown
+ attributes:
+ label: Operating System
+ description: If you know this bug occurs on multiple operating systems, select all you have tested.
+ multiple: true
+ options:
+ - Windows
+ - macOS
+ - Linux
+ - Other
+- type: textarea
+ attributes:
+ label: Version of MeshMC
+ description: The version of MeshMC used in the bug report.
+ placeholder: MeshMC 7.0.0
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Version of Qt
+ description: The version of Qt used in the bug report. You can find it in Help -> About MeshMC -> About Qt.
+ placeholder: Qt 6.3.0
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Description of bug
+ description: What did you expect to happen, what happened, and why is it incorrect?
+ placeholder: The cat button should show a cat, but it showed a dog instead!
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Steps to reproduce
+ description: A bulleted list, or an exported instance if relevant.
+ placeholder: "* Press the cat button"
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Suspected cause
+ description: If you know what could be causing this bug, describe it here.
+ validations:
+ required: false
+- type: checkboxes
+ attributes:
+ label: This issue is unique
+ options:
+ - label: I have searched the issue tracker and did not find an issue describing my bug.
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000000..37c7e6ebdc
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: true
+contact_links:
+ - name: MeshMC Discord
+ url: https://discord.gg/meshmc
+ about: Please ask for support here before opening an issue.
diff --git a/.github/ISSUE_TEMPLATE/rfc.yml b/.github/ISSUE_TEMPLATE/rfc.yml
new file mode 100644
index 0000000000..d9f5b0a981
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/rfc.yml
@@ -0,0 +1,68 @@
+# Template based on https://gitlab.archlinux.org/archlinux/rfcs/-/blob/0ba3b61e987e197f8d1901709409b8564958f78a/rfcs/0000-template.rst
+name: Request for Comment (RFC)
+description: Propose a larger change and start a discussion.
+labels: ["type: enhancement", "status: needs discussion", "status: needs triage"]
+body:
+- type: markdown
+ attributes:
+ value: |
+ ### Use this form to suggest a larger change for MeshMC.
+- type: textarea
+ attributes:
+ label: Goal
+ description: Short description, 1-2 sentences.
+ placeholder: Remove the cat from the launcher.
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Motivation
+ description: |
+ Introduce the topic. If this is a not-well-known section of MeshMC, a detailed explanation of the background is recommended.
+ Some example points of discussion:
+ - What specific problems are you facing right now that you're trying to address?
+ - Are there any previous discussions? Link to them and summarize them (don't force your readers to read them though!).
+ - Is there any precedent set by other software? If so, link to resources.
+ placeholder: I don't like cats. I think many users also don't like cats.
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Specification
+ description: A concrete, thorough explanation of what is being planned.
+ placeholder: Remove the cat button and all references to the cat from the codebase. Including resource files.
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Drawbacks
+ description: Carefully consider every possible objection and issue with your proposal. This section should be updated as feedback comes in from discussion.
+ placeholder: Some users might like cats.
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Unresolved Questions
+ description: |
+ Are there any portions of your proposal which need to be discussed with the community before the RFC can proceed?
+ Be careful here -- an RFC with a lot of remaining questions is likely to be stalled.
+ If your RFC is mostly unresolved questions and not too much substance, it may not be ready.
+ placeholder: Do a lot of users care about the cat?
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Alternatives Considered
+ description: A list of alternatives, that have been considered and offer equal or similar features to the proposed change.
+ placeholder: Maybe the cat could be replaced with an axolotl?
+ validations:
+ required: true
+- type: checkboxes
+ attributes:
+ label: This suggestion is unique
+ options:
+ - label: I have searched the issue tracker and did not find an issue describing my suggestion, especially not one that has been rejected.
+ required: true
+- type: textarea
+ attributes:
+ label: You may use the editor below to elaborate further.
diff --git a/.github/ISSUE_TEMPLATE/suggestion.yml b/.github/ISSUE_TEMPLATE/suggestion.yml
new file mode 100644
index 0000000000..53bd186531
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/suggestion.yml
@@ -0,0 +1,38 @@
+name: Suggestion
+description: Make a suggestion
+labels: [idea, needs-triage]
+body:
+- type: markdown
+ attributes:
+ value: |
+ ### Use this form to suggest a feature for MeshMC.
+- type: input
+ attributes:
+ label: Role
+ description: In what way do you use MeshMC that needs this feature?
+ placeholder: I play modded Minecraft.
+ validations:
+ required: true
+- type: input
+ attributes:
+ label: Suggestion
+ description: What do you want MeshMC to do?
+ placeholder: I want the cat button to meow.
+ validations:
+ required: true
+- type: input
+ attributes:
+ label: Benefit
+ description: Why do you need MeshMC to do this?
+ placeholder: so that I can always hear a cat when I need to.
+ validations:
+ required: true
+- type: checkboxes
+ attributes:
+ label: This suggestion is unique
+ options:
+ - label: I have searched the issue tracker and did not find an issue describing my suggestion, especially not one that has been rejected.
+ required: true
+- type: textarea
+ attributes:
+ label: You may use the editor below to elaborate further.
diff --git a/.github/actions/meshmc/package/linux/action.yml b/.github/actions/meshmc/package/linux/action.yml
new file mode 100644
index 0000000000..457ccb27ed
--- /dev/null
+++ b/.github/actions/meshmc/package/linux/action.yml
@@ -0,0 +1,153 @@
+name: Package for Linux
+description: Create Linux packages for MeshMC
+
+inputs:
+ version:
+ description: Launcher version
+ required: true
+ build-type:
+ description: Type for the build
+ required: true
+ default: Debug
+ artifact-name:
+ description: Name of the uploaded artifact
+ required: true
+ default: Linux
+ qt-version:
+ description: Version of Qt to use
+ required: true
+ gpg-private-key:
+ description: Private key for AppImage signing
+ required: false
+ gpg-private-key-id:
+ description: ID for the gpg-private-key, to select the signing key
+ required: false
+
+runs:
+ using: composite
+
+ steps:
+ - name: Cleanup Qt installation on Linux
+ shell: bash
+ run: |
+ rm -rf "$QT_PLUGIN_PATH"/printsupport
+ rm -rf "$QT_PLUGIN_PATH"/sqldrivers
+ rm -rf "$QT_PLUGIN_PATH"/help
+ rm -rf "$QT_PLUGIN_PATH"/designer
+ rm -rf "$QT_PLUGIN_PATH"/qmltooling
+ rm -rf "$QT_PLUGIN_PATH"/qmlls
+ rm -rf "$QT_PLUGIN_PATH"/qmllint
+ rm -rf "$QT_PLUGIN_PATH"/platformthemes/libqgtk3.so
+
+ - name: Setup build variables
+ shell: bash
+ run: |
+ # Fixup architecture naming for AppImages
+ dpkg_arch="$(dpkg-architecture -q DEB_HOST_ARCH_CPU)"
+ case "$dpkg_arch" in
+ "amd64")
+ APPIMAGE_ARCH="x86_64"
+ ;;
+ "arm64")
+ APPIMAGE_ARCH="aarch64"
+ ;;
+ *)
+ echo "# 🚨 The Debian architecture \"$deb_arch\" is not recognized!" >> "$GITHUB_STEP_SUMMARY"
+ exit 1
+ ;;
+ esac
+ echo "APPIMAGE_ARCH=$APPIMAGE_ARCH" >> "$GITHUB_ENV"
+
+ # Used for the file paths of libraries
+ echo "DEB_HOST_MULTIARCH=$(dpkg-architecture -q DEB_HOST_MULTIARCH)" >> "$GITHUB_ENV"
+
+ - name: Package AppImage
+ shell: bash
+ env:
+ VERSION: ${{ github.ref_type == 'tag' && github.ref_name || inputs.version }}
+ BUILD_DIR: build
+ INSTALL_APPIMAGE_DIR: install-appdir
+
+ GPG_PRIVATE_KEY: ${{ inputs.gpg-private-key }}
+ run: |
+ cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }} --prefix ${{ env.INSTALL_APPIMAGE_DIR }}
+
+ if [ '${{ inputs.gpg-private-key-id }}' != '' ]; then
+ echo "$GPG_PRIVATE_KEY" > privkey.asc
+ gpg --import privkey.asc
+ gpg --export --armor ${{ inputs.gpg-private-key-id }} > pubkey.asc
+ else
+ echo ":warning: Skipped code signing for Linux AppImage, as gpg key was not present." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ sharun lib4bin \
+ --hard-links \
+ --with-hooks \
+ --dst-dir "$INSTALL_APPIMAGE_DIR" \
+ "$INSTALL_APPIMAGE_DIR"/bin/* "$QT_PLUGIN_PATH"/*/*.so
+
+ cp ~/bin/AppImageUpdate.AppImage "$INSTALL_APPIMAGE_DIR"/bin/
+ # FIXME(@YongDo-Hyun): gamemode doesn't seem to be very portable with DBus. Find a way to make it work!
+ find "$INSTALL_APPIMAGE_DIR" -name '*gamemode*' -exec rm {} +
+
+ #disable OpenGL and Vulkan launcher features until https://github.com/VHSgunzo/sharun/issues/35
+ echo "LAUNCHER_DISABLE_GLVULKAN=1" > "$INSTALL_APPIMAGE_DIR"/.env
+ #makes the launcher use portals for file picking
+ echo "QT_QPA_PLATFORMTHEME=xdgdesktopportal" > "$INSTALL_APPIMAGE_DIR"/.env
+ ln -s org.projecttick.MeshMC.metainfo.xml "$INSTALL_APPIMAGE_DIR"/share/metainfo/org.projecttick.MeshMC.appdata.xml
+ ln -s share/applications/org.projecttick.MeshMC.desktop "$INSTALL_APPIMAGE_DIR"
+ ln -s share/icons/hicolor/256x256/apps/org.projecttick.MeshMC.png "$INSTALL_APPIMAGE_DIR"
+ mv "$INSTALL_APPIMAGE_DIR"/{sharun,AppRun}
+ ls -la "$INSTALL_APPIMAGE_DIR"
+
+ if [[ "${{ github.ref_type }}" == "tag" ]]; then
+ APPIMAGE_DEST="MeshMC-Linux-$APPIMAGE_ARCH.AppImage"
+ else
+ APPIMAGE_DEST="MeshMC-Linux-$VERSION-${{ inputs.build-type }}-$APPIMAGE_ARCH.AppImage"
+ fi
+
+ mkappimage \
+ --updateinformation "gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|MeshMC-Linux-$APPIMAGE_ARCH.AppImage.zsync" \
+ "$INSTALL_APPIMAGE_DIR" \
+ "$APPIMAGE_DEST"
+
+ - name: Package portable tarball
+ shell: bash
+ env:
+ BUILD_DIR: build
+
+ INSTALL_PORTABLE_DIR: install-portable
+ run: |
+ cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }} --prefix ${{ env.INSTALL_PORTABLE_DIR }}
+ cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
+
+ sharun lib4bin \
+ --with-hooks \
+ --hard-links \
+ --dst-dir "$INSTALL_PORTABLE_DIR" \
+ "$INSTALL_PORTABLE_DIR"/bin/* "$QT_PLUGIN_PATH"/*/*.so
+
+ # FIXME(@YongDo-Hyun): gamemode doesn't seem to be very portable with DBus. Find a way to make it work!
+ find "$INSTALL_PORTABLE_DIR" -name '*gamemode*' -exec rm {} +
+
+ for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f -o -type l); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt
+ cd ${{ env.INSTALL_PORTABLE_DIR }}
+ tar -czf ../MeshMC-portable.tar.gz *
+
+ - name: Upload binary tarball
+ uses: actions/upload-artifact@v7
+ with:
+ name: MeshMC-${{ inputs.artifact-name }}-Qt6-Portable-${{ inputs.version }}-${{ inputs.build-type }}
+ path: MeshMC-portable.tar.gz
+
+ - name: Upload AppImage
+ uses: actions/upload-artifact@v7
+ with:
+ name: MeshMC-${{ runner.os }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage
+ path: MeshMC-${{ runner.os }}-*${{ env.APPIMAGE_ARCH }}.AppImage
+
+ - name: Upload AppImage Zsync
+ uses: actions/upload-artifact@v7
+ with:
+ name: MeshMC-${{ runner.os }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage.zsync
+ path: MeshMC-${{ runner.os }}-*${{ env.APPIMAGE_ARCH }}.AppImage.zsync
diff --git a/.github/actions/meshmc/package/macos/action.yml b/.github/actions/meshmc/package/macos/action.yml
new file mode 100644
index 0000000000..2a1c432a6d
--- /dev/null
+++ b/.github/actions/meshmc/package/macos/action.yml
@@ -0,0 +1,146 @@
+name: Package for macOS
+description: Create a macOS package for MeshMC
+
+inputs:
+ version:
+ description: Launcher version
+ required: true
+ build-type:
+ description: Type for the build
+ required: true
+ default: Debug
+ artifact-name:
+ description: Name of the uploaded artifact
+ required: true
+ default: macOS
+ apple-codesign-cert:
+ description: Certificate for signing macOS builds
+ required: false
+ apple-codesign-password:
+ description: Password for signing macOS builds
+ required: false
+ apple-codesign-id:
+ description: Certificate ID for signing macOS builds
+ required: false
+ apple-notarize-apple-id:
+ description: Apple ID used for notarizing macOS builds
+ required: false
+ apple-notarize-team-id:
+ description: Team ID used for notarizing macOS builds
+ required: false
+ apple-notarize-password:
+ description: Password used for notarizing macOS builds
+ required: false
+ sparkle-ed25519-key:
+ description: Private key for signing Sparkle updates
+ required: false
+
+runs:
+ using: composite
+
+ steps:
+ - name: Fetch codesign certificate
+ shell: bash
+ run: |
+ echo '${{ inputs.apple-codesign-cert }}' | base64 --decode > codesign.p12
+ if [ -n '${{ inputs.apple-codesign-id }}' ]; then
+ security create-keychain -p '${{ inputs.apple-codesign-password }}' build.keychain
+ security default-keychain -s build.keychain
+ security unlock-keychain -p '${{ inputs.apple-codesign-password }}' build.keychain
+ security import codesign.p12 -k build.keychain -P '${{ inputs.apple-codesign-password }}' -T /usr/bin/codesign
+ security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k '${{ inputs.apple-codesign-password }}' build.keychain
+ else
+ echo ":warning: Using ad-hoc code signing for macOS, as certificate was not present." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Package
+ shell: bash
+ env:
+ BUILD_DIR: build
+ INSTALL_DIR: install
+ run: |
+ cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }}
+
+ cd ${{ env.INSTALL_DIR }}
+ chmod +x "MeshMC.app/Contents/MacOS/meshmc"
+
+ if [ -n '${{ inputs.apple-codesign-id }}' ]; then
+ APPLE_CODESIGN_ID='${{ inputs.apple-codesign-id }}'
+ ENTITLEMENTS_FILE='../branding/App.entitlements'
+ else
+ APPLE_CODESIGN_ID='-'
+ ENTITLEMENTS_FILE='../branding/AdhocSignedApp.entitlements'
+ fi
+
+ sudo codesign --sign "$APPLE_CODESIGN_ID" --deep --force --entitlements "$ENTITLEMENTS_FILE" --options runtime "MeshMC.app/Contents/MacOS/meshmc"
+
+ - name: Notarize
+ shell: bash
+ env:
+ INSTALL_DIR: install
+ run: |
+ cd ${{ env.INSTALL_DIR }}
+
+ if [ -n '${{ inputs.apple-notarize-password }}' ]; then
+ ditto -c -k --sequesterRsrc --keepParent "MeshMC.app" ../MeshMC.zip
+ xcrun notarytool submit ../MeshMC.zip \
+ --wait --progress \
+ --apple-id '${{ inputs.apple-notarize-apple-id }}' \
+ --team-id '${{ inputs.apple-notarize-team-id }}' \
+ --password '${{ inputs.apple-notarize-password }}'
+
+ xcrun stapler staple "MeshMC.app"
+ else
+ echo ":warning: Skipping notarization as credentials are not present." >> $GITHUB_STEP_SUMMARY
+ fi
+ ditto -c -k --sequesterRsrc --keepParent "MeshMC.app" ../MeshMC.zip
+
+ - name: Create DMG
+ shell: bash
+ env:
+ INSTALL_DIR: install
+ run: |
+ cd ${{ env.INSTALL_DIR }}
+
+ mkdir -p src
+ cp -R "MeshMC.app" src/
+
+ ln -s /Applications src/
+
+ hdiutil create \
+ -volname "MeshMC ${{ inputs.version }}" \
+ -srcfolder src \
+ -ov -format ULMO \
+ "../MeshMC.dmg"
+
+ - name: Make Sparkle signature
+ shell: bash
+ run: |
+ if [ '${{ inputs.sparkle-ed25519-key }}' != '' ]; then
+ echo '${{ inputs.sparkle-ed25519-key }}' > ed25519-priv.pem
+ signature_zip=$(/opt/homebrew/opt/openssl@3/bin/openssl pkeyutl -sign -rawin -in ${{ github.workspace }}/MeshMC.zip -inkey ed25519-priv.pem | openssl base64 | tr -d \\n)
+ signature_dmg=$(/opt/homebrew/opt/openssl@3/bin/openssl pkeyutl -sign -rawin -in ${{ github.workspace }}/MeshMC.dmg -inkey ed25519-priv.pem | openssl base64 | tr -d \\n)
+ rm ed25519-priv.pem
+ cat >> $GITHUB_STEP_SUMMARY << EOF
+ ### Artifact Information :information_source:
+ - :memo: Sparkle Signature (ed25519): \`$signature_zip\` (ZIP)
+ - :memo: Sparkle Signature (ed25519): \`$signature_dmg\` (DMG)
+ EOF
+ else
+ cat >> $GITHUB_STEP_SUMMARY << EOF
+ ### Artifact Information :information_source:
+ - :warning: Sparkle Signature (ed25519): No private key available (likely a pull request or fork)
+ EOF
+ fi
+
+ - name: Upload binary tarball
+ uses: actions/upload-artifact@v7
+ with:
+ name: MeshMC-${{ inputs.artifact-name }}-${{ inputs.version }}-${{ inputs.build-type }}
+ path: MeshMC.zip
+
+ - name: Upload disk image
+ uses: actions/upload-artifact@v7
+ with:
+ name: MeshMC-${{ inputs.artifact-name }}-${{ inputs.version }}-${{ inputs.build-type }}.dmg
+ path: MeshMC.dmg
diff --git a/.github/actions/meshmc/package/windows/action.yml b/.github/actions/meshmc/package/windows/action.yml
new file mode 100644
index 0000000000..33e3d42718
--- /dev/null
+++ b/.github/actions/meshmc/package/windows/action.yml
@@ -0,0 +1,142 @@
+name: Package for Windows
+description: Create a Windows package for MeshMC
+
+inputs:
+ version:
+ description: Launcher version
+ required: true
+ build-type:
+ description: Type for the build
+ required: true
+ default: Debug
+ artifact-name:
+ description: Name of the uploaded artifact
+ required: true
+ msystem:
+ description: MSYS2 subsystem to use
+ required: false
+ windows-codesign-cert:
+ description: Certificate for signing Windows builds
+ required: false
+ windows-codesign-password:
+ description: Password for signing Windows builds
+ required: false
+
+runs:
+ using: composite
+
+ steps:
+ - name: Package (MinGW)
+ if: ${{ inputs.msystem != '' }}
+ shell: msys2 {0}
+ env:
+ BUILD_DIR: build
+ INSTALL_DIR: install
+ run: |
+ cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }}
+ touch ${{ env.INSTALL_DIR }}/manifest.txt
+ for l in $(find ${{ env.INSTALL_DIR }} -type f); do l=$(cygpath -u $l); l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_DIR }}/}; l=${l#./}; echo $l; done >> ${{ env.INSTALL_DIR }}/manifest.txt
+
+ - name: Package (MSVC)
+ if: ${{ inputs.msystem == '' }}
+ shell: pwsh
+ env:
+ BUILD_DIR: build
+ INSTALL_DIR: install
+ run: |
+ cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }}
+
+ cd ${{ github.workspace }}
+
+ Get-ChildItem ${{ env.INSTALL_DIR }} -Recurse | ForEach FullName | Resolve-Path -Relative | %{ $_.TrimStart('.\') } | %{ $_.TrimStart('${{ env.INSTALL_DIR }}') } | %{ $_.TrimStart('\') } | Out-File -FilePath ${{ env.INSTALL_DIR }}/manifest.txt
+
+ - name: Fetch codesign certificate
+ shell: bash # yes, we are not using MSYS2 or PowerShell here
+ run: |
+ echo '${{ inputs.windows-codesign-cert }}' | base64 --decode > codesign.pfx
+
+ - name: Sign executable
+ shell: pwsh
+ env:
+ INSTALL_DIR: install
+ run: |
+ if (Get-Content ./codesign.pfx){
+ cd ${{ env.INSTALL_DIR }}
+ # We ship the exact same executable for portable and non-portable editions, so signing just once is fine
+ SignTool sign /fd sha256 /td sha256 /f ../codesign.pfx /p '${{ inputs.windows-codesign-password }}' /tr http://timestamp.digicert.com meshmc.exe
+ } else {
+ ":warning: Skipped code signing for Windows, as certificate was not present." >> $env:GITHUB_STEP_SUMMARY
+ }
+
+ - name: Package (MinGW, portable)
+ if: ${{ inputs.msystem != '' }}
+ shell: msys2 {0}
+ env:
+ BUILD_DIR: build
+ INSTALL_DIR: install
+ INSTALL_PORTABLE_DIR: install-portable
+ run: |
+ cp -r ${{ env.INSTALL_DIR }} ${{ env.INSTALL_PORTABLE_DIR }} # cmake install on Windows is slow, let's just copy instead
+ cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
+ for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f); do l=$(cygpath -u $l); l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done >> ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt
+
+ - name: Package (MSVC, portable)
+ if: ${{ inputs.msystem == '' }}
+ shell: pwsh
+ env:
+ BUILD_DIR: build
+ INSTALL_DIR: install
+ INSTALL_PORTABLE_DIR: install-portable
+ run: |
+ cp -r ${{ env.INSTALL_DIR }} ${{ env.INSTALL_PORTABLE_DIR }} # cmake install on Windows is slow, let's just copy instead
+ cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
+
+ Get-ChildItem ${{ env.INSTALL_PORTABLE_DIR }} -Recurse | ForEach FullName | Resolve-Path -Relative | %{ $_.TrimStart('.\') } | %{ $_.TrimStart('${{ env.INSTALL_PORTABLE_DIR }}') } | %{ $_.TrimStart('\') } | Out-File -FilePath ${{ env.INSTALL_DIR }}/manifest.txt
+
+ - name: Package (installer)
+ shell: pwsh
+ env:
+ BUILD_DIR: build
+ INSTALL_DIR: install
+
+ NSCURL_VERSION: "v24.9.26.122"
+ NSCURL_SHA256: "AEE6C4BE3CB6455858E9C1EE4B3AFE0DB9960FA03FE99CCDEDC28390D57CCBB0"
+ run: |
+ New-Item -Name NSISPlugins -ItemType Directory
+ Invoke-Webrequest https://github.com/negrutiu/nsis-nscurl/releases/download/"${{ env.NSCURL_VERSION }}"/NScurl.zip -OutFile NSISPlugins\NScurl.zip
+ $nscurl_hash = Get-FileHash NSISPlugins\NScurl.zip -Algorithm Sha256 | Select-Object -ExpandProperty Hash
+ if ( $nscurl_hash -ne "${{ env.nscurl_sha256 }}") {
+ echo "::error:: NSCurl.zip sha256 mismatch"
+ exit 1
+ }
+ Expand-Archive -Path NSISPlugins\NScurl.zip -DestinationPath NSISPlugins\NScurl
+
+ cd ${{ env.INSTALL_DIR }}
+ makensis -NOCD "${{ github.workspace }}/${{ env.BUILD_DIR }}/win_install.nsi"
+
+ - name: Sign installer
+ shell: pwsh
+ run: |
+ if (Get-Content ./codesign.pfx){
+ SignTool sign /fd sha256 /td sha256 /f codesign.pfx /p '${{ inputs.windows-codesign-password }}' /tr http://timestamp.digicert.com MeshMC-Setup.exe
+ } else {
+ ":warning: Skipped code signing for Windows, as certificate was not present." >> $env:GITHUB_STEP_SUMMARY
+ }
+
+ - name: Upload binary zip
+ uses: actions/upload-artifact@v5
+ with:
+ name: MeshMC-${{ inputs.artifact-name }}-${{ inputs.version }}-${{ inputs.build-type }}
+ path: install/**
+
+ - name: Upload portable zip
+ uses: actions/upload-artifact@v5
+ with:
+ name: MeshMC-${{ inputs.artifact-name }}-Portable-${{ inputs.version }}-${{ inputs.build-type }}
+ path: install-portable/**
+
+ - name: Upload installer
+ uses: actions/upload-artifact@v5
+ with:
+ name: MeshMC-${{ inputs.artifact-name }}-Setup-${{ inputs.version }}-${{ inputs.build-type }}
+ path: MeshMC-Setup.exe
diff --git a/.github/actions/meshmc/setup-dependencies/action.yml b/.github/actions/meshmc/setup-dependencies/action.yml
new file mode 100644
index 0000000000..9ab7781441
--- /dev/null
+++ b/.github/actions/meshmc/setup-dependencies/action.yml
@@ -0,0 +1,89 @@
+name: Setup Dependencies
+description: Install and setup dependencies for building MeshMC
+
+inputs:
+ build-type:
+ description: Type for the build
+ required: true
+ default: Debug
+ artifact-name:
+ description: Name of the uploaded artifact
+ required: true
+ msystem:
+ description: MSYS2 subsystem to use
+ required: false
+ vcvars-arch:
+ description: Visual Studio architecture to use
+ required: false
+ qt-architecture:
+ description: Qt architecture
+ required: false
+ qt-version:
+ description: Version of Qt to use
+ required: true
+ github-token:
+ description: GitHub token for package feed authentication
+ required: false
+ default: ${{ github.token }}
+
+outputs:
+ build-type:
+ description: Type of build used
+ value: ${{ inputs.build-type }}
+ qt-version:
+ description: Version of Qt used
+ value: ${{ inputs.qt-version }}
+
+runs:
+ using: composite
+
+ steps:
+ - name: Setup Linux dependencies
+ if: ${{ runner.os == 'Linux' }}
+ uses: ./.github/actions/meshmc/setup-dependencies/linux
+ with:
+ github-token: ${{ inputs.github-token }}
+
+ - name: Setup macOS dependencies
+ if: ${{ runner.os == 'macOS' }}
+ uses: ./.github/actions/meshmc/setup-dependencies/macos
+ with:
+ build-type: ${{ inputs.build-type }}
+ github-token: ${{ inputs.github-token }}
+
+ - name: Setup Windows dependencies
+ if: ${{ runner.os == 'Windows' }}
+ uses: ./.github/actions/meshmc/setup-dependencies/windows
+ with:
+ build-type: ${{ inputs.build-type }}
+ msystem: ${{ inputs.msystem }}
+ vcvars-arch: ${{ inputs.vcvars-arch }}
+ github-token: ${{ inputs.github-token }}
+
+ # TODO(@YongDo-Hyun): Get this working on MSYS2!
+ - name: Setup ccache
+ if: ${{ (runner.os != 'Windows' || inputs.msystem == '') && inputs.build-type == 'Debug' }}
+ uses: hendrikmuhs/ccache-action@v1.2.22
+ with:
+ variant: sccache
+ create-symlink: ${{ runner.os != 'Windows' }}
+ key: ${{ runner.os }}-${{ runner.arch }}-${{ inputs.artifact-name }}-sccache
+
+ - name: Use ccache on debug builds
+ if: ${{ inputs.build-type == 'Debug' }}
+ shell: bash
+ env:
+ # Only use ccache on MSYS2
+ CCACHE_VARIANT: ${{ (runner.os == 'Windows' && inputs.msystem != '') && 'ccache' || 'sccache' }}
+ run: |
+ echo "CMAKE_C_COMPILER_LAUNCHER=$CCACHE_VARIANT" >> "$GITHUB_ENV"
+ echo "CMAKE_CXX_COMPILER_LAUNCHER=$CCACHE_VARIANT" >> "$GITHUB_ENV"
+
+ - name: Install Qt
+ if: ${{ inputs.msystem == '' }}
+ uses: jurplel/install-qt-action@v4
+ with:
+ aqtversion: "==3.1.*"
+ version: ${{ inputs.qt-version }}
+ modules: qtimageformats qtnetworkauth qt5compat
+ cache: ${{ inputs.build-type == 'Debug' }}
diff --git a/.github/actions/meshmc/setup-dependencies/linux/action.yml b/.github/actions/meshmc/setup-dependencies/linux/action.yml
new file mode 100644
index 0000000000..46cb40e8a5
--- /dev/null
+++ b/.github/actions/meshmc/setup-dependencies/linux/action.yml
@@ -0,0 +1,59 @@
+name: Setup Linux dependencies
+description: Install and setup dependencies for building MeshMC
+
+inputs:
+ github-token:
+ description: GitHub token for authentication
+ required: true
+
+runs:
+ using: composite
+
+ steps:
+ - name: Install host dependencies
+ shell: bash
+ run: |
+ sudo apt-get -y update
+ sudo apt-get -y install \
+ dpkg-dev \
+ ninja-build extra-cmake-modules pkg-config scdoc \
+ cmark gamemode-dev libarchive-dev libcmark-dev libqrencode-dev zlib1g-dev \
+ libxcb-cursor-dev libtomlplusplus-dev libvulkan-dev
+
+ - name: Setup AppImage tooling
+ shell: bash
+ env:
+ GH_TOKEN: ${{ inputs.github-token }}
+ run: |
+ # Determinate AppImage architecture to use
+ dpkg_arch="$(dpkg-architecture -q DEB_HOST_ARCH_CPU)"
+ case "$dpkg_arch" in
+ "amd64")
+ APPIMAGE_ARCH="x86_64"
+ ;;
+ "arm64")
+ APPIMAGE_ARCH="aarch64"
+ ;;
+ *)
+ echo "# 🚨 The Debian architecture \"$deb_arch\" is not recognized!" >> "$GITHUB_STEP_SUMMARY"
+ exit 1
+ ;;
+ esac
+
+ gh release download \
+ --repo VHSgunzo/sharun \
+ --pattern "sharun-$APPIMAGE_ARCH-aio" \
+ --output ~/bin/sharun
+
+ # FIXME!: revert this to probonopd/go-appimage once https://github.com/probonopd/go-appimage/pull/377 is merged!
+ gh release download continuous \
+ --repo DioEgizio/go-appimage \
+ --pattern "mkappimage-*-$APPIMAGE_ARCH.AppImage" \
+ --output ~/bin/mkappimage
+
+ gh release download \
+ --repo AppImageCommunity/AppImageUpdate \
+ --pattern "AppImageUpdate-$APPIMAGE_ARCH.AppImage" \
+ --output ~/bin/AppImageUpdate.AppImage
+ chmod +x ~/bin/*
+ echo "$HOME/bin" >> "$GITHUB_PATH"
diff --git a/.github/actions/meshmc/setup-dependencies/macos/action.yml b/.github/actions/meshmc/setup-dependencies/macos/action.yml
new file mode 100644
index 0000000000..3eb5b37fa6
--- /dev/null
+++ b/.github/actions/meshmc/setup-dependencies/macos/action.yml
@@ -0,0 +1,52 @@
+name: Setup macOS dependencies
+
+inputs:
+ build-type:
+ description: Type for the build
+ required: true
+ default: Debug
+ github-token:
+ description: GitHub token for package feed authentication
+ required: true
+
+runs:
+ using: composite
+
+ steps:
+ - name: Install dependencies
+ shell: bash
+ run: |
+ brew update
+ brew install ninja extra-cmake-modules temurin@17 mono autoconf libarchive
+
+ - name: Set JAVA_HOME
+ shell: bash
+ run: |
+ echo "JAVA_HOME=$(/usr/libexec/java_home -v 17)" >> "$GITHUB_ENV"
+
+ - name: Setup vcpkg cache
+ if: ${{ inputs.build-type == 'Debug' }}
+ shell: bash
+ env:
+ USERNAME: ${{ github.repository_owner }}
+ GITHUB_TOKEN: ${{ inputs.github-token }}
+ FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
+ NUGET_RW: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
+ run: |
+ mono `vcpkg fetch nuget | tail -n 1` \
+ sources add \
+ -Source "$FEED_URL" \
+ -StorePasswordInClearText \
+ -Name GitHubPackages \
+ -UserName "$USERNAME" \
+ -Password "$GITHUB_TOKEN"
+ mono `vcpkg fetch nuget | tail -n 1` \
+ setapikey "$GITHUB_TOKEN" \
+ -Source "$FEED_URL"
+ MODE=$( [ "$NUGET_RW" = "true" ] && echo "readwrite" || echo "read" )
+ echo "VCPKG_BINARY_SOURCES=clear;nuget,$FEED_URL,$MODE" >> "$GITHUB_ENV"
+
+ - name: Setup vcpkg environment
+ shell: bash
+ run: |
+ echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> "$GITHUB_ENV"
diff --git a/.github/actions/meshmc/setup-dependencies/windows/action.yml b/.github/actions/meshmc/setup-dependencies/windows/action.yml
new file mode 100644
index 0000000000..a06b38d389
--- /dev/null
+++ b/.github/actions/meshmc/setup-dependencies/windows/action.yml
@@ -0,0 +1,114 @@
+name: Setup Windows Dependencies
+description: Install and setup dependencies for building MeshMC
+
+inputs:
+ build-type:
+ description: Type for the build
+ required: true
+ default: Debug
+ msystem:
+ description: MSYS2 subsystem to use
+ required: false
+ vcvars-arch:
+ description: Visual Studio architecture to use
+ required: true
+ default: amd64
+ github-token:
+ description: GitHub token for package feed authentication
+ required: true
+
+runs:
+ using: composite
+
+ steps:
+ # NOTE: Installed on MinGW as well for SignTool
+ - name: Enter VS Developer shell
+ if: ${{ runner.os == 'Windows' }}
+ uses: ilammy/msvc-dev-cmd@v1
+ with:
+ arch: ${{ inputs.vcvars-arch }}
+ vsversion: 2022
+
+ - name: Setup Java (MSVC)
+ uses: actions/setup-java@v5
+ with:
+ # NOTE(@YongDo-Hyun): We should probably stay on Zulu.
+ # Temurin doesn't have Java 17 builds for WoA
+ distribution: zulu
+ java-version: 17
+
+ - name: Setup vcpkg cache (MSVC)
+ if: ${{ inputs.msystem == '' && inputs.build-type == 'Debug' }}
+ shell: pwsh
+ env:
+ USERNAME: ${{ github.repository_owner }}
+ GITHUB_TOKEN: ${{ inputs.github-token }}
+ FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
+ NUGET_RW: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
+ run: |
+ .$(vcpkg fetch nuget) `
+ sources add `
+ -Source "$env:FEED_URL" `
+ -StorePasswordInClearText `
+ -Name GitHubPackages `
+ -UserName "$env:USERNAME" `
+ -Password "$env:GITHUB_TOKEN"
+ .$(vcpkg fetch nuget) `
+ setapikey "$env:GITHUB_TOKEN" `
+ -Source "$env:FEED_URL"
+ $mode = if ($env:NUGET_RW -eq 'true') { 'readwrite' } else { 'read' }
+ "VCPKG_BINARY_SOURCES=clear;nuget,$env:FEED_URL,$mode" | Out-File -Append $env:GITHUB_ENV
+
+ - name: Setup vcpkg environment (MSVC)
+ if: ${{ inputs.msystem == '' }}
+ shell: bash
+ run: |
+ echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> "$GITHUB_ENV"
+
+ - name: Setup MSYS2 (MinGW)
+ if: ${{ inputs.msystem != '' }}
+ uses: msys2/setup-msys2@v2
+ with:
+ msystem: ${{ inputs.msystem }}
+ update: true
+ install: >-
+ git
+ pacboy: >-
+ toolchain:p
+ ccache:p
+ cmake:p
+ extra-cmake-modules:p
+ ninja:p
+ qt6-base:p
+ qt6-svg:p
+ qt6-imageformats:p
+ qt6-networkauth:p
+ qt6-5compat:p
+ cmark:p
+ qrencode:p
+ tomlplusplus:p
+ libarchive:p
+
+ - name: List pacman packages (MinGW)
+ if: ${{ inputs.msystem != '' }}
+ shell: msys2 {0}
+ run: |
+ pacman -Qe
+
+ - name: Retrieve ccache cache (MinGW)
+ if: ${{ inputs.msystem != '' && inputs.build-type == 'Debug' }}
+ uses: actions/cache@v5.0.4
+ with:
+ path: '${{ github.workspace }}\.ccache'
+ key: ${{ runner.os }}-mingw-w64-ccache-${{ github.run_id }}
+ restore-keys: |
+ ${{ runner.os }}-mingw-w64-ccache
+
+ - name: Setup ccache (MinGW)
+ if: ${{ inputs.msystem != '' && inputs.build-type == 'Debug' }}
+ shell: msys2 {0}
+ run: |
+ ccache --set-config=cache_dir='${{ github.workspace }}\.ccache'
+ ccache --set-config=max_size='500M'
+ ccache --set-config=compression=true
+ ccache -p # Show config
diff --git a/.github/actions/uvim/test_artifacts/action.yml b/.github/actions/uvim/test_artifacts/action.yml
new file mode 100644
index 0000000000..79d1aa82f6
--- /dev/null
+++ b/.github/actions/uvim/test_artifacts/action.yml
@@ -0,0 +1,55 @@
+name: 'test_artifacts'
+description: "Upload failed test artifacts"
+runs:
+ using: "composite"
+ steps:
+ - name: Collect matrix properties for naming
+ uses: actions/github-script@v8
+ id: matrix-props
+ env:
+ MATRIX_PROPS: ${{ toJSON(matrix) }}
+ with:
+ # An array-flattening-to-string JavaScript function.
+ script: |
+ const f = function (x) { return x.toString().length > 0; }
+ const g = function (x) {
+ return (Array.isArray(x))
+ ? x.filter(f)
+ .map((function (h) { return function (y) { return h(y); }; })(g))
+ .join('-')
+ : x;
+ }
+ return Object.values(JSON.parse(process.env.MATRIX_PROPS))
+ .filter(f)
+ .map(g)
+ .join('-');
+ # By default, the JSON-encoded return value of the function is
+ # set as the "result".
+ result-encoding: string
+ - name: Upload failed tests
+ uses: actions/upload-artifact@v7
+ with:
+ # Name of the artifact to upload.
+ name: ${{ format('GH-{0}-{1}-{2}-{3}-{4}-failed-tests',
+ github.run_id,
+ github.run_attempt,
+ github.job,
+ strategy.job-index,
+ steps.matrix-props.outputs.result) }}
+
+ # A file, directory or wildcard pattern that describes what
+ # to upload.
+ path: |
+ ${{ github.workspace }}/runtime/indent/testdir/*.fail
+ ${{ github.workspace }}/runtime/syntax/testdir/failed/*
+ ${{ github.workspace }}/src/testdir/failed/*
+ # The desired behavior if no files are found using the
+ # provided path.
+ if-no-files-found: ignore
+
+ # Duration after which artifact will expire in days. 0 means
+ # using repository settings.
+ retention-days: 0
+
+ # If true, an artifact with a matching name will be deleted
+ overwrite: true
diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml
new file mode 100644
index 0000000000..70acfdfd7e
--- /dev/null
+++ b/.github/codeql/codeql-config.yml
@@ -0,0 +1,3 @@
+query-filters:
+ - exclude:
+ id: cpp/fixme-comment
diff --git a/.github/dco.yml b/.github/dco.yml
new file mode 100644
index 0000000000..60c37b9425
--- /dev/null
+++ b/.github/dco.yml
@@ -0,0 +1,2 @@
+allowRemediationCommits:
+ individual: false
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000000..bd2abdad87
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,9 @@
+<!--
+Hey there! Thanks for your contribution for MeshMC.
+
+Please make sure that your commits are signed off and please sign CLA first.
+If you don't know how that works, check out our contribution guidelines: https://github.com/Project-Tick/MeshMC/blob/master/CONTRIBUTING.md#signing-your-work
+If you already created your commits, you can run `git rebase --signoff develop` to retroactively sign-off all your commits and `git push --force` to override what you have pushed already.
+
+Note that signing and signing-off are two different things!
+-->
diff --git a/.github/workflows/cgit-ci.yml b/.github/workflows/cgit-ci.yml
new file mode 100644
index 0000000000..9248d2bcef
--- /dev/null
+++ b/.github/workflows/cgit-ci.yml
@@ -0,0 +1,60 @@
+name: "cgit: CI"
+
+on:
+ push:
+ paths:
+ - 'cgit/**'
+ - '.github/workflows/cgit-ci.yml'
+ pull_request:
+ paths:
+ - 'cgit/**'
+ - '.github/workflows/cgit-ci.yml'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest]
+
+ defaults:
+ run:
+ working-directory: cgit
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ submodules: true
+
+ - name: Install dependencies (Linux)
+ if: runner.os == 'Linux'
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y \
+ build-essential \
+ libssl-dev \
+ zlib1g-dev \
+ libcurl4-openssl-dev \
+ asciidoc \
+ xmlto
+
+ - name: Install dependencies (macOS)
+ if: runner.os == 'macOS'
+ run: brew install openssl asciidoc xmlto
+
+ - name: Build git
+ run: |
+ cd git
+ make -j$(nproc 2>/dev/null || sysctl -n hw.logicalcpu) prefix=/usr/local NO_GETTEXT=1
+
+ - name: Build cgit
+ run: make -j$(nproc 2>/dev/null || sysctl -n hw.logicalcpu)
+
+ - name: Run tests
+ run: make test || true
diff --git a/.github/workflows/cmark-ci.yml b/.github/workflows/cmark-ci.yml
new file mode 100644
index 0000000000..45daf6082f
--- /dev/null
+++ b/.github/workflows/cmark-ci.yml
@@ -0,0 +1,129 @@
+name: "cmark: CI"
+
+on:
+ push:
+ branches-ignore:
+ - 'dependabot/**'
+ paths:
+ - 'cmark/**'
+ - '.github/workflows/cmark-ci.yml'
+ pull_request:
+ paths:
+ - 'cmark/**'
+ - '.github/workflows/cmark-ci.yml'
+ workflow_dispatch:
+
+jobs:
+ linter:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - name: Install clang-tidy
+ run: sudo apt-get install -y clang-tidy
+ - name: lint with clang-tidy
+ working-directory: cmark
+ run: make lint
+ env:
+ CC: clang
+ CXX: clang++
+
+ posix:
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [linux, macos]
+ cc: [clang, gcc]
+ build_type: [shared, static]
+ sanitizers: ['', ASan]
+ include:
+ - os: 'linux'
+ image: 'ubuntu-latest'
+ - os: 'macos'
+ image: 'macos-latest'
+ - cc: 'clang'
+ cxx: 'clang++'
+ - cc: 'gcc'
+ cxx: 'g++'
+ - build_type: 'shared'
+ cmake_shared: 'YES'
+ - build_type: 'static'
+ cmake_shared: 'NO'
+ - sanitizers: 'ASan'
+ san_cflags: '-fsanitize=address,undefined -fno-sanitize-recover=all'
+ - sanitizers: 'ASan'
+ os: 'linux'
+ cc: 'gcc'
+ build_type: 'shared'
+ test_env: 'LD_PRELOAD=$(gcc -print-file-name=libasan.so)'
+ - sanitizers: 'ASan'
+ os: 'linux'
+ cc: 'clang'
+ build_type: 'shared'
+ asan_cflags: '-shared-libasan'
+ test_env: 'LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so)'
+ - sanitizers: 'ASan'
+ build_type: 'shared'
+ asan_opts: 'detect_leaks=0'
+ - sanitizers: 'ASan'
+ cc: 'gcc'
+ build_type: 'static'
+ asan_cflags: '-static-libasan'
+ exclude:
+ - os: 'macos'
+ cc: 'gcc'
+ - os: 'macos'
+ sanitizers: 'ASan'
+ build_type: 'shared'
+
+ runs-on: ${{ matrix.image }}
+
+ env:
+ ASAN_OPTIONS: ${{ matrix.asan_opts }}
+ CC: ${{ matrix.cc }}
+ CXX: ${{ matrix.cxx }}
+ CFLAGS: '${{ matrix.san_cflags }} ${{ matrix.asan_cflags }}'
+ CXXFLAGS: '${{ matrix.san_cflags }} ${{ matrix.asan_cflags }}'
+
+ steps:
+ - uses: actions/checkout@v6
+ - name: Build and test
+ working-directory: cmark
+ run: |
+ cmake \
+ -DBUILD_SHARED_LIBS=${{ matrix.cmake_shared }} \
+ -DCMAKE_BUILD_TYPE=Debug \
+ -S . -B build
+ cmake --build build
+ ${{ matrix.test_env }} ctest --test-dir build --output-on-failure
+
+ windows:
+ runs-on: windows-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ build_type: [shared, static]
+ include:
+ - build_type: 'shared'
+ cmake_shared: 'YES'
+ - build_type: 'static'
+ cmake_shared: 'NO'
+ steps:
+ - uses: actions/checkout@v6
+ - uses: ilammy/msvc-dev-cmd@v1
+ - name: Build and test
+ working-directory: cmark
+ run: |
+ cmake ^
+ -DBUILD_SHARED_LIBS=${{ matrix.cmake_shared }} ^
+ -DCMAKE_BUILD_TYPE=Debug ^
+ -S . -B build
+ cmake --build build
+ ctest --test-dir build -C Debug --output-on-failure
+ shell: cmd
+ - name: Upload artifact
+ if: ${{ matrix.build_type == 'static' }}
+ uses: actions/upload-artifact@v7
+ with:
+ name: cmark windows ${{ matrix.build_type }}
+ path: cmark/build/src/Debug/cmark.exe
+ if-no-files-found: error
diff --git a/.github/workflows/cmark-fuzz.yml b/.github/workflows/cmark-fuzz.yml
new file mode 100644
index 0000000000..fd999ca929
--- /dev/null
+++ b/.github/workflows/cmark-fuzz.yml
@@ -0,0 +1,30 @@
+name: "cmark: Fuzz"
+
+on:
+ pull_request:
+ paths:
+ - 'cmark/**'
+ - '.github/workflows/cmark-fuzz.yml'
+
+jobs:
+ Fuzzing:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - name: Build Fuzzers
+ uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'cmark'
+ dry-run: false
+ - name: Run Fuzzers
+ uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'cmark'
+ fuzz-seconds: 600
+ dry-run: false
+ - name: Upload Crash
+ uses: actions/upload-artifact@v7
+ if: failure()
+ with:
+ name: artifacts
+ path: ./out/artifacts
diff --git a/.github/workflows/corebinutils-ci.yml b/.github/workflows/corebinutils-ci.yml
new file mode 100644
index 0000000000..34c9b3fcfd
--- /dev/null
+++ b/.github/workflows/corebinutils-ci.yml
@@ -0,0 +1,69 @@
+name: "corebinutils: CI"
+
+on:
+ push:
+ paths:
+ - 'corebinutils/**'
+ - '.github/workflows/corebinutils-ci.yml'
+ pull_request:
+ paths:
+ - 'corebinutils/**'
+ - '.github/workflows/corebinutils-ci.yml'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ build-linux:
+ runs-on: ubuntu-latest
+
+ defaults:
+ run:
+ working-directory: corebinutils
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y \
+ build-essential \
+ bmake \
+ libbsd-dev \
+ libmd-dev
+
+ - name: Configure
+ run: |
+ if [ -x ./configure ]; then
+ ./configure
+ fi
+
+ - name: Build
+ run: |
+ if [ -f GNUmakefile ]; then
+ make -f GNUmakefile -j$(nproc) || true
+ else
+ make -j$(nproc) || true
+ fi
+
+ build-freebsd:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+
+ - name: Build on FreeBSD
+ uses: vmactions/freebsd-vm@v1
+ with:
+ usesh: true
+ prepare: |
+ pkg install -y gmake
+ run: |
+ cd corebinutils
+ if [ -x ./configure ]; then
+ ./configure
+ fi
+ make -j$(sysctl -n hw.ncpu) || true
diff --git a/.github/workflows/forgewrapper-build.yml b/.github/workflows/forgewrapper-build.yml
new file mode 100644
index 0000000000..30010f6e1c
--- /dev/null
+++ b/.github/workflows/forgewrapper-build.yml
@@ -0,0 +1,62 @@
+name: "ForgeWrapper: Build"
+
+on:
+ push:
+ branches: [master]
+ paths:
+ - 'forgewrapper/**'
+ - '.github/workflows/forgewrapper-build.yml'
+ pull_request:
+ branches: [master]
+ paths:
+ - 'forgewrapper/**'
+ - '.github/workflows/forgewrapper-build.yml'
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: forgewrapper
+ steps:
+ - uses: actions/checkout@v6
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ distribution: "temurin"
+ java-version: "8"
+ architecture: x64
+ - name: Build with Gradle
+ run: |
+ chmod +x ./gradlew
+ ./gradlew build -iS
+ - uses: actions/upload-artifact@v7
+ with:
+ name: ForgeWrapper
+ path: forgewrapper/build/libs
+
+ publish:
+ if: startsWith(github.ref, 'refs/tags/')
+ needs: build
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: forgewrapper
+ steps:
+ - uses: actions/checkout@v6
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ distribution: "temurin"
+ java-version: "8"
+ architecture: x64
+ - name: Build with Gradle
+ env:
+ IS_PUBLICATION: true
+ run: |
+ chmod +x ./gradlew
+ ./gradlew publish -iS
+ - uses: actions/upload-artifact@v7
+ with:
+ name: ForgeWrapper-Release
+ path: forgewrapper/build/libs
diff --git a/.github/workflows/genqrcode-ci.yml b/.github/workflows/genqrcode-ci.yml
new file mode 100644
index 0000000000..9931f66ec9
--- /dev/null
+++ b/.github/workflows/genqrcode-ci.yml
@@ -0,0 +1,71 @@
+name: "genqrcode: CI"
+
+on:
+ push:
+ paths:
+ - 'genqrcode/**'
+ - '.github/workflows/genqrcode-ci.yml'
+ pull_request:
+ paths:
+ - 'genqrcode/**'
+ - '.github/workflows/genqrcode-ci.yml'
+
+jobs:
+ cmake:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ env:
+ BUILD_TYPE: Release
+ defaults:
+ run:
+ working-directory: genqrcode
+ steps:
+ - uses: actions/checkout@v6
+ - name: Install vcpkg deps (Windows)
+ if: matrix.os == 'windows-latest'
+ uses: lukka/run-vcpkg@v6
+ with:
+ vcpkgArguments: getopt:x64-windows libiconv:x64-windows libpng:x64-windows
+ vcpkgDirectory: '${{ github.workspace }}/vcpkg'
+ vcpkgGitCommitId: '2a42024b53ebb512fb5dd63c523338bf26c8489c'
+ - name: Install deps (macOS)
+ if: matrix.os == 'macos-latest'
+ run: brew install pkg-config libpng
+ - name: Configure CMake
+ if: matrix.os != 'windows-latest'
+ run: cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DWITH_TESTS=yes -DBUILD_SHARED_LIBS=on -S . -B build
+ - name: Configure CMake (Windows)
+ if: matrix.os == 'windows-latest'
+ run: cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake -DWITH_TESTS=yes -S . -B build
+ - name: Build
+ run: cmake --build build --config $BUILD_TYPE -j 2
+ - name: Test
+ run: ctest --test-dir build -C $BUILD_TYPE
+
+ autotools:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest]
+ defaults:
+ run:
+ working-directory: genqrcode
+ steps:
+ - uses: actions/checkout@v6
+ - name: Install deps (macOS)
+ if: matrix.os == 'macos-latest'
+ run: brew install automake autoconf pkg-config libpng
+ - name: Generate configure
+ run: ./autogen.sh
+ - name: Configure
+ run: ./configure --with-tests
+ - name: Build
+ run: make -j 2
+ - name: Test
+ run: make check
+ - name: Distcheck
+ run: make -j 2 distcheck
diff --git a/.github/workflows/images4docker-build.yml b/.github/workflows/images4docker-build.yml
new file mode 100644
index 0000000000..4657d06d29
--- /dev/null
+++ b/.github/workflows/images4docker-build.yml
@@ -0,0 +1,85 @@
+name: "images4docker: Build"
+
+on:
+ push:
+ branches: ["trunk", "master"]
+ paths:
+ - "images4docker/dockerfiles/**"
+ - ".github/workflows/images4docker-build.yml"
+ schedule:
+ - cron: "17 3 * * *"
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ packages: write
+
+jobs:
+ prepare:
+ runs-on: ubuntu-latest
+ outputs:
+ matrix: ${{ steps.make.outputs.matrix }}
+ count: ${{ steps.make.outputs.count }}
+ steps:
+ - uses: actions/checkout@v6
+ - id: make
+ run: |
+ set -euo pipefail
+
+ entries=()
+ for f in images4docker/dockerfiles/*.Dockerfile; do
+ name="$(basename "$f" .Dockerfile)"
+ entries+=("$name|$f")
+ done
+
+ json='{"include":['
+ first=true
+ for entry in "${entries[@]}"; do
+ IFS='|' read -r name dockerfile <<< "$entry"
+ $first || json+=','
+ first=false
+ json+="{\"name\":\"$name\",\"dockerfile\":\"$dockerfile\"}"
+ done
+ json+=']}'
+
+ echo "matrix=$json" >> "$GITHUB_OUTPUT"
+ echo "count=${#entries[@]}" >> "$GITHUB_OUTPUT"
+
+ build:
+ needs: prepare
+ if: needs.prepare.outputs.count != '0'
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ max-parallel: 6
+ matrix: ${{ fromJSON(needs.prepare.outputs.matrix) }}
+ steps:
+ - uses: actions/checkout@v6
+
+ - name: Login to GHCR
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Compute image tags
+ id: tagmeta
+ run: |
+ set -euo pipefail
+ short_sha="${GITHUB_SHA::12}"
+ ts="$(date -u +%Y%m%d-%H%M%S)"
+ echo "sha_tag=sha-${short_sha}" >> "$GITHUB_OUTPUT"
+ echo "immutable_tag=${ts}-r${GITHUB_RUN_ID}-a${GITHUB_RUN_ATTEMPT}-${short_sha}" >> "$GITHUB_OUTPUT"
+
+ - name: Build and push image
+ uses: docker/build-push-action@v6
+ with:
+ context: images4docker
+ file: ${{ matrix.dockerfile }}
+ push: true
+ provenance: false
+ tags: |
+ ghcr.io/${{ github.repository_owner }}/images/${{ matrix.name }}:latest
+ ghcr.io/${{ github.repository_owner }}/images/${{ matrix.name }}:${{ steps.tagmeta.outputs.sha_tag }}
+ ghcr.io/${{ github.repository_owner }}/images/${{ matrix.name }}:${{ steps.tagmeta.outputs.immutable_tag }}
diff --git a/.github/workflows/json4cpp-ci.yml b/.github/workflows/json4cpp-ci.yml
new file mode 100644
index 0000000000..2646c1b5c9
--- /dev/null
+++ b/.github/workflows/json4cpp-ci.yml
@@ -0,0 +1,166 @@
+name: "json4cpp: CI"
+
+on:
+ push:
+ branches:
+ - develop
+ - master
+ - release/*
+ paths:
+ - 'json4cpp/**'
+ - '.github/workflows/json4cpp-ci.yml'
+ pull_request:
+ paths:
+ - 'json4cpp/**'
+ - '.github/workflows/json4cpp-ci.yml'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+concurrency:
+ group: json4cpp-${{ github.workflow }}-${{ github.ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ ci_test_gcc:
+ runs-on: ubuntu-latest
+ container: gcc:latest
+ steps:
+ - uses: actions/checkout@v6
+ - name: Get latest CMake and ninja
+ uses: lukka/get-cmake@v4
+ - name: Run CMake
+ run: cmake -S json4cpp -B build -DJSON_CI=On
+ - name: Build
+ run: cmake --build build --target ci_test_gcc
+
+ ci_static_analysis:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ target: [ci_test_amalgamation, ci_test_single_header, ci_cppcheck, ci_cpplint, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata, ci_reuse_compliance, ci_test_valgrind]
+ steps:
+ - uses: actions/checkout@v6
+ - name: Install Valgrind
+ run: sudo apt-get update ; sudo apt-get install -y valgrind
+ - name: Get latest CMake and ninja
+ uses: lukka/get-cmake@v4
+ - name: Run CMake
+ run: cmake -S json4cpp -B build -DJSON_CI=On
+ - name: Build
+ run: cmake --build build --target ${{ matrix.target }}
+
+ ci_static_analysis_clang:
+ runs-on: ubuntu-latest
+ container: silkeh/clang:dev
+ strategy:
+ fail-fast: false
+ matrix:
+ target: [ci_test_clang, ci_clang_tidy, ci_test_clang_sanitizer, ci_clang_analyze, ci_single_binaries]
+ steps:
+ - name: Install dependencies
+ run: apt-get update ; apt-get install -y git clang-tools iwyu unzip
+ - uses: actions/checkout@v6
+ - name: Get latest CMake and ninja
+ uses: lukka/get-cmake@v4
+ - name: Run CMake
+ run: cmake -S json4cpp -B build -DJSON_CI=On
+ - name: Build
+ run: cmake --build build --target ${{ matrix.target }}
+
+ ci_test_compilers_gcc:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ compiler: ['7', '8', '9', '10', '11', '12', '13', '14', '15', 'latest']
+ container: gcc:${{ matrix.compiler }}
+ steps:
+ - uses: actions/checkout@v6
+ - name: Get latest CMake and ninja
+ uses: lukka/get-cmake@v4
+ - name: Run CMake
+ run: cmake -S json4cpp -B build -DJSON_CI=On
+ - name: Build
+ run: cmake --build build --target ci_test_compiler_default
+
+ ci_test_compilers_clang:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ compiler: ['11', '12', '13', '14', '15-bullseye', '16', '17', '18', '19', '20', 'latest']
+ container: silkeh/clang:${{ matrix.compiler }}
+ steps:
+ - uses: actions/checkout@v6
+ - name: Get latest CMake and ninja
+ uses: lukka/get-cmake@v4
+ - name: Run CMake
+ run: cmake -S json4cpp -B build -DJSON_CI=On
+ - name: Build
+ run: cmake --build build --target ci_test_compiler_default
+
+ ci_test_coverage:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y build-essential cmake lcov ninja-build locales gcc-multilib g++-multilib
+ sudo locale-gen de_DE
+ sudo update-locale
+ - name: Run CMake
+ run: cmake -S json4cpp -B build -DJSON_CI=On
+ - name: Build
+ run: cmake --build build --target ci_test_coverage
+ - name: Upload coverage report
+ uses: actions/upload-artifact@v7
+ with:
+ name: code-coverage-report
+ path: build/html
+
+ macos:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [macos-13, macos-14, macos-15]
+ steps:
+ - uses: actions/checkout@v6
+ - name: Run CMake
+ run: cmake -S json4cpp -B build -DJSON_CI=On
+ - name: Build
+ run: cmake --build build --target ci_test_clang
+
+ windows:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [windows-2022, windows-2025]
+ steps:
+ - uses: actions/checkout@v6
+ - name: Run CMake
+ run: cmake -S json4cpp -B build -DJSON_CI=On -G "Visual Studio 17 2022"
+ - name: Build
+ run: cmake --build build --config Release --target ci_test_msvc
+
+ codeql:
+ runs-on: ubuntu-latest
+ permissions:
+ security-events: write
+ steps:
+ - uses: actions/checkout@v6
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v4
+ with:
+ languages: cpp
+ - name: Build
+ run: |
+ cmake -S json4cpp -B build
+ cmake --build build
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v4
diff --git a/.github/workflows/meshmc-backport.yml b/.github/workflows/meshmc-backport.yml
new file mode 100644
index 0000000000..d468fd6986
--- /dev/null
+++ b/.github/workflows/meshmc-backport.yml
@@ -0,0 +1,28 @@
+name: "MeshMC: Backport"
+
+on:
+ pull_request_target:
+ types: [closed, labeled]
+
+permissions: {}
+
+jobs:
+ backport:
+ permissions:
+ contents: write
+ pull-requests: write
+ actions: write
+
+ name: Backport Pull Request
+ if: github.repository_owner == 'Project-Tick' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ ref: ${{ github.event.pull_request.head.sha }}
+
+ - name: Create backport PRs
+ uses: korthout/backport-action@v4.3.0
+ with:
+ pull_description: |-
+ Bot-based backport to `${target_branch}`, triggered by a label in #${pull_number}.
diff --git a/.github/workflows/meshmc-blocked-prs.yml b/.github/workflows/meshmc-blocked-prs.yml
new file mode 100644
index 0000000000..0010801540
--- /dev/null
+++ b/.github/workflows/meshmc-blocked-prs.yml
@@ -0,0 +1,257 @@
+name: Blocked/Stacked Pull Requests Automation
+
+on:
+ pull_request_target:
+ types:
+ - opened
+ - reopened
+ - edited
+ - synchronize
+ workflow_dispatch:
+ inputs:
+ pr_id:
+ description: Local Pull Request number to work on
+ required: true
+ type: number
+
+permissions: {}
+
+jobs:
+ blocked_status:
+ name: Check Blocked Status
+ runs-on: ubuntu-slim
+
+ steps:
+ - name: Generate token
+ id: generate-token
+ uses: actions/create-github-app-token@v3
+ with:
+ app-id: ${{ vars.PULL_REQUEST_APP_ID }}
+ private-key: ${{ secrets.PULL_REQUEST_APP_PRIVATE_KEY }}
+
+ - name: Setup From Dispatch Event
+ if: github.event_name == 'workflow_dispatch'
+ id: dispatch_event_setup
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ PR_NUMBER: ${{ inputs.pr_id }}
+ run: |
+ # setup env for the rest of the workflow
+ OWNER=$(dirname "${{ github.repository }}")
+ REPO=$(basename "${{ github.repository }}")
+ PR_JSON=$(
+ gh api \
+ -H "Accept: application/vnd.github.raw+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ "/repos/$OWNER/$REPO/pulls/$PR_NUMBER"
+ )
+ echo "PR_JSON=$PR_JSON" >> "$GITHUB_ENV"
+
+ - name: Setup Environment
+ id: env_setup
+ env:
+ EVENT_PR_JSON: ${{ toJSON(github.event.pull_request) }}
+ run: |
+ # setup env for the rest of the workflow
+ PR_JSON=${PR_JSON:-"$EVENT_PR_JSON"}
+ {
+ echo "REPO=$(jq -r '.base.repo.name' <<< "$PR_JSON")"
+ echo "OWNER=$(jq -r '.base.repo.owner.login' <<< "$PR_JSON")"
+ echo "PR_NUMBER=$(jq -r '.number' <<< "$PR_JSON")"
+ echo "JOB_DATA=$(jq -c '
+ {
+ "repo": .base.repo.name,
+ "owner": .base.repo.owner.login,
+ "repoUrl": .base.repo.html_url,
+ "prNumber": .number,
+ "prHeadSha": .head.sha,
+ "prHeadLabel": .head.label,
+ "prBody": (.body // ""),
+ "prLabels": (reduce .labels[].name as $l ([]; . + [$l]))
+ }
+ ' <<< "$PR_JSON")"
+ } >> "$GITHUB_ENV"
+
+
+ - name: Find Blocked/Stacked PRs in body
+ id: pr_ids
+ run: |
+ prs=$(
+ jq -c '
+ .prBody as $body
+ | (
+ $body |
+ reduce (
+ . | scan("[Bb]locked (?:[Bb]y|[Oo]n):? #([0-9]+)")
+ | map({
+ "type": "Blocked on",
+ "number": ( . | tonumber )
+ })
+ ) as $i ([]; . + [$i[]])
+ ) as $bprs
+ | (
+ $body |
+ reduce (
+ . | scan("[Ss]tacked [Oo]n:? #([0-9]+)")
+ | map({
+ "type": "Stacked on",
+ "number": ( . | tonumber )
+ })
+ ) as $i ([]; . + [$i[]])
+ ) as $sprs
+ | ($bprs + $sprs) as $prs
+ | {
+ "blocking": $prs,
+ "numBlocking": ( $prs | length),
+ }
+ ' <<< "$JOB_DATA"
+ )
+ echo "prs=$prs" >> "$GITHUB_OUTPUT"
+
+ - name: Collect Blocked PR Data
+ id: blocking_data
+ if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ BLOCKING_PRS: ${{ steps.pr_ids.outputs.prs }}
+ run: |
+ blocked_pr_data=$(
+ while read -r pr_data ; do
+ gh api \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ "/repos/$OWNER/$REPO/pulls/$(jq -r '.number' <<< "$pr_data")" \
+ | jq -c --arg type "$(jq -r '.type' <<< "$pr_data")" \
+ '
+ . | {
+ "type": $type,
+ "number": .number,
+ "merged": .merged,
+ "state": (if .state == "open" then "Open" elif .merged then "Merged" else "Closed" end),
+ "labels": (reduce .labels[].name as $l ([]; . + [$l])),
+ "basePrUrl": .html_url,
+ "baseRepoName": .head.repo.name,
+ "baseRepoOwner": .head.repo.owner.login,
+ "baseRepoUrl": .head.repo.html_url,
+ "baseSha": .head.sha,
+ "baseRefName": .head.ref,
+ }
+ '
+ done < <(jq -c '.blocking[]' <<< "$BLOCKING_PRS") | jq -c -s
+ )
+ {
+ echo "data=$blocked_pr_data";
+ echo "all_merged=$(jq -r 'all(.[] | (.type == "Stacked on" and .merged) or (.type == "Blocked on" and (.state != "Open")); .)' <<< "$blocked_pr_data")";
+ echo "current_blocking=$(jq -c 'map(
+ select(
+ (.type == "Stacked on" and (.merged | not)) or
+ (.type == "Blocked on" and (.state == "Open"))
+ ) | .number
+ )' <<< "$blocked_pr_data" )";
+ } >> "$GITHUB_OUTPUT"
+
+ - name: Add 'blocked' Label if Missing
+ id: label_blocked
+ if: "(fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0) && !contains(fromJSON(env.JOB_DATA).prLabels, 'status: blocked') && !fromJSON(steps.blocking_data.outputs.all_merged)"
+ continue-on-error: true
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ run: |
+ gh -R ${{ github.repository }} issue edit --add-label 'status: blocked' "$PR_NUMBER"
+
+ - name: Remove 'blocked' Label if All Dependencies Are Merged
+ id: unlabel_blocked
+ if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 && fromJSON(steps.blocking_data.outputs.all_merged)
+ continue-on-error: true
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ run: |
+ gh -R ${{ github.repository }} issue edit --remove-label 'status: blocked' "$PR_NUMBER"
+
+ - name: Apply 'blocking' Label to Unmerged Dependencies
+ id: label_blocking
+ if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
+ continue-on-error: true
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ BLOCKING_ISSUES: ${{ steps.blocking_data.outputs.current_blocking }}
+ run: |
+ while read -r pr ; do
+ gh -R ${{ github.repository }} issue edit --add-label 'status: blocking' "$pr" || true
+ done < <(jq -c '.[]' <<< "$BLOCKING_ISSUES")
+
+ - name: Apply Blocking PR Status Check
+ id: blocked_check
+ if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
+ continue-on-error: true
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ BLOCKING_DATA: ${{ steps.blocking_data.outputs.data }}
+ run: |
+ pr_head_sha=$(jq -r '.prHeadSha' <<< "$JOB_DATA")
+ # create commit Status, overwrites previous identical context
+ while read -r pr_data ; do
+ DESC=$(
+ jq -r 'if .type == "Stacked on" then
+ "Stacked PR #" + (.number | tostring) + " is " + (if .merged then "" else "not yet " end) + "merged"
+ else
+ "Blocking PR #" + (.number | tostring) + " is " + (if .state == "Open" then "" else "not yet " end) + "merged or closed"
+ end ' <<< "$pr_data"
+ )
+ gh api \
+ --method POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ "/repos/${OWNER}/${REPO}/statuses/${pr_head_sha}" \
+ -f "state=$(jq -r 'if (.type == "Stacked on" and .merged) or (.type == "Blocked on" and (.state != "Open")) then "success" else "failure" end' <<< "$pr_data")" \
+ -f "target_url=$(jq -r '.basePrUrl' <<< "$pr_data" )" \
+ -f "description=$DESC" \
+ -f "context=ci/blocking-pr-check:$(jq '.number' <<< "$pr_data")"
+ done < <(jq -c '.[]' <<< "$BLOCKING_DATA")
+
+ - name: Context Comment
+ id: generate-comment
+ if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
+ continue-on-error: true
+ env:
+ BLOCKING_DATA: ${{ steps.blocking_data.outputs.data }}
+ run: |
+ COMMENT_PATH="$(pwd)/temp_comment_file.txt"
+ echo '<h3>PR Dependencies :pushpin:</h3>' > "$COMMENT_PATH"
+ echo >> "$COMMENT_PATH"
+ pr_head_label=$(jq -r '.prHeadLabel' <<< "$JOB_DATA")
+ while read -r pr_data ; do
+ base_pr=$(jq -r '.number' <<< "$pr_data")
+ base_ref_name=$(jq -r '.baseRefName' <<< "$pr_data")
+ base_repo_owner=$(jq -r '.baseRepoOwner' <<< "$pr_data")
+ base_repo_name=$(jq -r '.baseRepoName' <<< "$pr_data")
+ compare_url="https://github.com/$base_repo_owner/$base_repo_name/compare/$base_ref_name...$pr_head_label"
+ status=$(jq -r '
+ if .type == "Stacked on" then
+ if .merged then ":heavy_check_mark: Merged" else ":x: Not Merged (" + .state + ")" end
+ else
+ if .state != "Open" then ":white_check_mark: " + .state else ":x: Open" end
+ end
+ ' <<< "$pr_data")
+ type=$(jq -r '.type' <<< "$pr_data")
+ echo " - $type #$base_pr $status [(compare)]($compare_url)" >> "$COMMENT_PATH"
+ done < <(jq -c '.[]' <<< "$BLOCKING_DATA")
+
+ {
+ echo 'body<<EOF';
+ cat "${COMMENT_PATH}";
+ echo 'EOF';
+ } >> "$GITHUB_OUTPUT"
+
+ - name: 💬 PR Comment
+ if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
+ continue-on-error: true
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ COMMENT_BODY: ${{ steps.generate-comment.outputs.body }}
+ run: |
+ gh -R ${{ github.repository }} issue comment "$PR_NUMBER" \
+ --body "$COMMENT_BODY" \
+ --create-if-none \
+ --edit-last
+
diff --git a/.github/workflows/meshmc-build.yml b/.github/workflows/meshmc-build.yml
new file mode 100644
index 0000000000..d7b0a2335e
--- /dev/null
+++ b/.github/workflows/meshmc-build.yml
@@ -0,0 +1,190 @@
+name: "MeshMC: Build"
+
+concurrency:
+ group: meshmc-${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ push:
+ branches:
+ - 'master'
+ paths:
+ - 'meshmc/**'
+ - '.github/workflows/meshmc-build.yml'
+ - '.github/actions/meshmc/**'
+ merge_group:
+ types: [checks_requested]
+ pull_request:
+ paths:
+ - 'meshmc/**'
+ - '.github/workflows/meshmc-build.yml'
+ - '.github/actions/meshmc/**'
+ workflow_call:
+ inputs:
+ build-type:
+ description: Type of build (Debug or Release)
+ type: string
+ default: Debug
+ environment:
+ description: Deployment environment to run under
+ type: string
+ workflow_dispatch:
+ inputs:
+ build-type:
+ description: Type of build (Debug or Release)
+ type: string
+ default: Debug
+
+permissions: {}
+
+jobs:
+ build:
+ name: Build (${{ matrix.artifact-name }})
+
+ environment: ${{ inputs.environment || '' }}
+
+ permissions:
+ contents: read
+ id-token: write
+ packages: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - os: ubuntu-24.04
+ artifact-name: Linux
+ cmake-preset: linux
+ qt-version: 6.10.2
+
+ - os: ubuntu-24.04-arm
+ artifact-name: Linux-aarch64
+ cmake-preset: linux
+ qt-version: 6.10.2
+
+ - os: windows-2022
+ artifact-name: Windows-MinGW-w64
+ cmake-preset: windows_mingw
+ msystem: CLANG64
+ vcvars-arch: amd64_x86
+
+ - os: windows-11-arm
+ artifact-name: Windows-MinGW-arm64
+ cmake-preset: windows_mingw
+ msystem: CLANGARM64
+ vcvars-arch: arm64
+
+ - os: windows-2022
+ artifact-name: Windows-MSVC
+ cmake-preset: windows_msvc
+ vcvars-arch: amd64
+ qt-version: 6.10.2
+
+ - os: windows-11-arm
+ artifact-name: Windows-MSVC-arm64
+ cmake-preset: windows_msvc
+ vcvars-arch: arm64
+ qt-version: 6.10.2
+
+ - os: macos-26
+ artifact-name: macOS
+ cmake-preset: macos_universal
+ macosx-deployment-target: 12.0
+ qt-version: 6.9.3
+
+ runs-on: ${{ matrix.os }}
+
+ defaults:
+ run:
+ shell: ${{ matrix.msystem != '' && 'msys2 {0}' || 'bash' }}
+ working-directory: meshmc
+
+ env:
+ ARTIFACT_NAME: ${{ matrix.artifact-name }}-Qt6
+ BUILD_PLATFORM: official
+ BUILD_TYPE: ${{ inputs.build-type || 'Debug' }}
+ CMAKE_PRESET: ${{ matrix.cmake-preset }}
+ MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx-deployment-target }}
+
+ steps:
+ ##
+ # SETUP
+ ##
+
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ submodules: true
+
+ - name: Setup dependencies
+ id: setup-dependencies
+ uses: ./.github/actions/meshmc/setup-dependencies
+ with:
+ build-type: ${{ env.BUILD_TYPE }}
+ artifact-name: ${{ matrix.artifact-name }}
+ msystem: ${{ matrix.msystem }}
+ vcvars-arch: ${{ matrix.vcvars-arch }}
+ qt-version: ${{ matrix.qt-version }}
+
+ ##
+ # BUILD
+ ##
+
+ - name: Configure project
+ run: |
+ cmake --preset "$CMAKE_PRESET"
+
+ - name: Run build
+ run: |
+ cmake --build --preset "$CMAKE_PRESET" --config "$BUILD_TYPE"
+
+ - name: Run tests
+ run: |
+ ctest --preset "$CMAKE_PRESET" --build-config "$BUILD_TYPE"
+
+ ##
+ # PACKAGE
+ ##
+
+ - name: Get short version
+ id: short-version
+ shell: bash
+ run: |
+ echo "version=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
+
+ - name: Package (Linux)
+ if: ${{ runner.os == 'Linux' }}
+ uses: ./.github/actions/meshmc/package/linux
+ with:
+ version: ${{ steps.short-version.outputs.version }}
+ build-type: ${{ steps.setup-dependencies.outputs.build-type }}
+ artifact-name: ${{ matrix.artifact-name }}
+ qt-version: ${{ steps.setup-dependencies.outputs.qt-version }}
+ gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
+ gpg-private-key-id: ${{ secrets.GPG_PRIVATE_KEY_ID }}
+
+ - name: Package (macOS)
+ if: ${{ runner.os == 'macOS' }}
+ uses: ./.github/actions/meshmc/package/macos
+ with:
+ version: ${{ steps.short-version.outputs.version }}
+ build-type: ${{ steps.setup-dependencies.outputs.build-type }}
+ artifact-name: ${{ matrix.artifact-name }}
+ apple-codesign-cert: ${{ secrets.APPLE_CODESIGN_CERT }}
+ apple-codesign-password: ${{ secrets.APPLE_CODESIGN_PASSWORD }}
+ apple-codesign-id: ${{ secrets.APPLE_CODESIGN_ID }}
+ apple-notarize-apple-id: ${{ secrets.APPLE_NOTARIZE_APPLE_ID }}
+ apple-notarize-team-id: ${{ secrets.APPLE_NOTARIZE_TEAM_ID }}
+ apple-notarize-password: ${{ secrets.APPLE_NOTARIZE_PASSWORD }}
+ sparkle-ed25519-key: ${{ secrets.SPARKLE_ED25519_KEY }}
+
+ - name: Package (Windows)
+ if: ${{ runner.os == 'Windows' }}
+ uses: ./.github/actions/meshmc/package/windows
+ with:
+ version: ${{ steps.short-version.outputs.version }}
+ build-type: ${{ env.BUILD_TYPE }}
+ artifact-name: ${{ matrix.artifact-name }}
+ windows-codesign-cert: ${{ secrets.WINDOWS_CODESIGN_CERT }}
+ windows-codesign-password: ${{ secrets.WINDOWS_CODESIGN_PASSWORD }}
+ msystem: ${{ matrix.msystem }}
diff --git a/.github/workflows/meshmc-codeql.yml b/.github/workflows/meshmc-codeql.yml
new file mode 100644
index 0000000000..6dd764849a
--- /dev/null
+++ b/.github/workflows/meshmc-codeql.yml
@@ -0,0 +1,59 @@
+name: "MeshMC: CodeQL"
+
+concurrency:
+ group: meshmc-codeql-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ merge_group:
+ types: [checks_requested]
+ pull_request:
+ paths:
+ - 'meshmc/**'
+ - '.github/workflows/meshmc-codeql.yml'
+ workflow_dispatch:
+
+permissions: {}
+
+jobs:
+ CodeQL:
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+ security-events: write
+
+ defaults:
+ run:
+ working-directory: meshmc
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+ with:
+ submodules: "true"
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v4
+ with:
+ config-file: ./.github/codeql/codeql-config.yml
+ queries: security-and-quality
+ languages: cpp, java
+
+ - name: Setup dependencies
+ uses: ./.github/actions/meshmc/setup-dependencies
+ with:
+ build-type: Debug
+ qt-version: 6.9.3
+
+ - name: Configure and Build
+ run: |
+ cmake --preset linux -DLauncher_USE_PCH=OFF
+ cmake --build --preset linux --config Debug
+
+ - name: Run tests
+ run: |
+ ctest --preset linux --build-config Debug --extra-verbose --output-on-failure
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v4
diff --git a/.github/workflows/meshmc-container.yml b/.github/workflows/meshmc-container.yml
new file mode 100644
index 0000000000..3a41e15bcd
--- /dev/null
+++ b/.github/workflows/meshmc-container.yml
@@ -0,0 +1,178 @@
+name: "MeshMC: Container"
+
+concurrency:
+ group: meshmc-container-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ push:
+ branches:
+ - 'master'
+ paths:
+ - 'meshmc/Containerfile'
+ - '.github/workflows/meshmc-container.yml'
+ merge_group:
+ types: [checks_requested]
+ pull_request:
+ paths:
+ - 'meshmc/Containerfile'
+ - '.github/workflows/meshmc-container.yml'
+ workflow_dispatch:
+
+permissions: {}
+
+env:
+ REGISTRY: ghcr.io
+
+jobs:
+ build:
+ name: Build (${{ matrix.arch }})
+
+ permissions:
+ contents: read
+ packages: write
+
+ outputs:
+ image-name: ${{ steps.image-name.outputs.image-name }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - arch: arm64
+ os: ubuntu-24.04-arm
+ - arch: amd64
+ os: ubuntu-24.04-arm
+
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ - name: Set image name
+ id: image-name
+ run: |
+ echo "image-name=${REGISTRY}/${GITHUB_REPOSITORY_OWNER,,}/devcontainer" >> "$GITHUB_OUTPUT"
+
+ - name: Install Podman
+ uses: redhat-actions/podman-install@main
+ if: ${{ runner.arch == 'X64' || runner.arch == 'X86' }}
+ with:
+ github-token: ${{ github.token }}
+
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ - name: Determine metadata for image
+ id: image-metadata
+ uses: docker/metadata-action@v6
+ with:
+ images: |
+ ${{ steps.image-name.outputs.image-name }}
+ flavor: |
+ latest=false
+ tags: |
+ type=raw,value=latest,enable=${{ github.event.merge_group.base_ref == 'refs/heads/develop' }}
+ type=sha
+ type=sha,format=long
+ type=ref,event=branch
+ type=ref,event=tag
+
+ - name: Build image
+ id: build-image
+ uses: redhat-actions/buildah-build@v2
+ with:
+ containerfiles: |
+ ./meshmc/Containerfile
+ tags: ${{ steps.image-metadata.outputs.tags }}
+ labels: ${{ steps.image-metadata.outputs.labels }}
+
+ - name: Push image
+ id: push-image
+ if: ${{ github.event_name != 'pull_request' }}
+ uses: redhat-actions/push-to-registry@v2
+ with:
+ tags: ${{ steps.build-image.outputs.tags }}
+ username: ${{ github.repository_owner }}
+ password: ${{ github.token }}
+ tls-verify: true
+
+ - name: Export image digest
+ if: ${{ github.event_name != 'pull_request' }}
+ env:
+ DIGEST: ${{ steps.push-image.outputs.digest }}
+ run: |
+ mkdir -p "$RUNNER_TEMP"/digests
+ touch "$RUNNER_TEMP"/digests/"${DIGEST#sha256:}"
+
+ - name: Upload digest artifact
+ if: ${{ github.event_name != 'pull_request' }}
+ uses: actions/upload-artifact@v7
+ with:
+ name: digests-${{ matrix.arch }}
+ path: ${{ runner.temp }}/digests/*
+ if-no-files-found: error
+ retention-days: 1
+
+ manifest:
+ name: Create manifest
+ needs: [build]
+ if: ${{ github.event_name != 'pull_request' }}
+
+ permissions:
+ contents: read
+ packages: write
+
+ runs-on: ubuntu-24.04
+
+ steps:
+ - name: Download digests
+ uses: actions/download-artifact@v8
+ with:
+ path: ${{ runner.temp }}/digests
+ pattern: digests-*
+ merge-multiple: true
+
+ - name: Install Podman
+ if: ${{ runner.arch == 'X64' || runner.arch == 'X86' }}
+ uses: redhat-actions/podman-install@main
+ with:
+ github-token: ${{ github.token }}
+
+ - name: Login to registry
+ uses: redhat-actions/podman-login@v1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.repository_owner }}
+ password: ${{ github.token }}
+
+ - name: Determine metadata for manifest
+ id: manifest-metadata
+ uses: docker/metadata-action@v6
+ with:
+ images: |
+ ${{ needs.build.outputs.image-name }}
+ flavor: |
+ latest=false
+ tags: |
+ type=raw,value=latest,enable=${{ github.event.merge_group.base_ref == 'refs/heads/develop' }}
+ type=sha
+ type=sha,format=long
+ type=ref,event=branch
+ type=ref,event=tag
+
+ - name: Create manifest list
+ working-directory: ${{ runner.temp }}/digests
+ env:
+ IMAGE_NAME: ${{ needs.build.outputs.image-name }}
+ run: |
+ while read -r tag; do
+ podman manifest create "$tag" \
+ $(printf "$IMAGE_NAME@sha256:%s " *)
+ done <<< "$DOCKER_METADATA_OUTPUT_TAGS"
+
+ - name: Push manifest
+ uses: redhat-actions/push-to-registry@v2
+ with:
+ tags: ${{ steps.manifest-metadata.outputs.tags }}
+ username: ${{ github.repository_owner }}
+ password: ${{ github.token }}
+ tls-verify: true
diff --git a/.github/workflows/meshmc-flake-update.yml b/.github/workflows/meshmc-flake-update.yml
new file mode 100644
index 0000000000..c0be2756d4
--- /dev/null
+++ b/.github/workflows/meshmc-flake-update.yml
@@ -0,0 +1,39 @@
+name: "MeshMC: Update Flake"
+
+on:
+ schedule:
+ - cron: "0 0 * * 0"
+ workflow_dispatch:
+
+permissions: {}
+
+jobs:
+ update-flake:
+ if: github.repository_owner == 'Project-Tick'
+
+ permissions:
+ contents: write
+ pull-requests: write
+
+ runs-on: ubuntu-latest
+
+ defaults:
+ run:
+ working-directory: meshmc
+
+ steps:
+ - uses: actions/checkout@v6
+ - uses: cachix/install-nix-action@v31
+
+ - uses: DeterminateSystems/update-flake-lock@v28
+ with:
+ path-to-flake-dir: meshmc
+ commit-msg: "chore(nix): update lockfile"
+ pr-title: "chore(nix): update lockfile"
+ pr-labels: |
+ platform: Linux
+ area: packaging
+ complexity: low
+ priority: low
+ type: robot
+ changelog:omit
diff --git a/.github/workflows/meshmc-merge-blocking-pr.yml b/.github/workflows/meshmc-merge-blocking-pr.yml
new file mode 100644
index 0000000000..3542a470e0
--- /dev/null
+++ b/.github/workflows/meshmc-merge-blocking-pr.yml
@@ -0,0 +1,64 @@
+name: Merged Blocking Pull Request Automation
+
+on:
+ pull_request_target:
+ types:
+ - closed
+ workflow_dispatch:
+ inputs:
+ pr_id:
+ description: Local Pull Request number to work on
+ required: true
+ type: number
+
+permissions: {}
+
+jobs:
+ update-blocked-status:
+ name: Update Blocked Status
+ runs-on: ubuntu-slim
+
+ # a pr that was a `blocking:<id>` label was merged.
+ # find the open pr's it was blocked by and trigger a refresh of their state
+ if: "${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'status: blocking') }}"
+
+ steps:
+ - name: Generate token
+ id: generate-token
+ uses: actions/create-github-app-token@v3
+ with:
+ app-id: ${{ vars.PULL_REQUEST_APP_ID }}
+ private-key: ${{ secrets.PULL_REQUEST_APP_PRIVATE_KEY }}
+
+ - name: Gather Dependent PRs
+ id: gather_deps
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ PR_NUMBER: ${{ inputs.pr_id || github.event.pull_request.number }}
+ run: |
+ blocked_prs=$(
+ gh -R ${{ github.repository }} pr list --label 'status: blocked' --json 'number,body' \
+ | jq -c --argjson pr "$PR_NUMBER" '
+ reduce ( .[] | select(
+ .body |
+ scan("(?:blocked (?:by|on)|stacked on):? #([0-9]+)") |
+ map(tonumber) |
+ any(.[]; . == $pr)
+ )) as $i ([]; . + [$i])
+ '
+ )
+ {
+ echo "deps=$blocked_prs"
+ echo "numdeps=$(jq -r '. | length' <<< "$blocked_prs")"
+ } >> "$GITHUB_OUTPUT"
+
+ - name: Trigger Blocked PR Workflows for Dependants
+ if: fromJSON(steps.gather_deps.outputs.numdeps) > 0
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ DEPS: ${{ steps.gather_deps.outputs.deps }}
+ run: |
+ while read -r pr ; do
+ gh -R ${{ github.repository }} workflow run 'blocked-prs.yml' -r "${{ github.ref_name }}" -f pr_id="$pr"
+ done < <(jq -c '.[].number' <<< "$DEPS")
+
diff --git a/.github/workflows/meshmc-nix.yml b/.github/workflows/meshmc-nix.yml
new file mode 100644
index 0000000000..21af121a34
--- /dev/null
+++ b/.github/workflows/meshmc-nix.yml
@@ -0,0 +1,122 @@
+name: "MeshMC: Nix"
+
+concurrency:
+ group: meshmc-nix-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ push:
+ branches:
+ - "master"
+ - "release-*"
+ tags:
+ - "*"
+ paths:
+ - "meshmc/**.cpp"
+ - "meshmc/**.h"
+ - "meshmc/**.java"
+ - "meshmc/**.ui"
+ - "meshmc/**.md"
+ - "meshmc/**.nix"
+ - "meshmc/nix/**"
+ - "meshmc/flake.lock"
+ - "meshmc/buildconfig/**"
+ - "meshmc/cmake/**"
+ - "meshmc/launcher/**"
+ - "meshmc/libraries/**"
+ - "meshmc/branding/**"
+ - "meshmc/tests/**"
+ - "meshmc/CMakeLists.txt"
+ - ".github/workflows/meshmc-nix.yml"
+ pull_request:
+ paths:
+ - "meshmc/**.cpp"
+ - "meshmc/**.h"
+ - "meshmc/**.java"
+ - "meshmc/**.ui"
+ - "meshmc/**.md"
+ - "meshmc/**.nix"
+ - "meshmc/nix/**"
+ - "meshmc/flake.lock"
+ - "meshmc/buildconfig/**"
+ - "meshmc/cmake/**"
+ - "meshmc/launcher/**"
+ - "meshmc/libraries/**"
+ - "meshmc/branding/**"
+ - "meshmc/tests/**"
+ - "meshmc/CMakeLists.txt"
+ - ".github/workflows/meshmc-nix.yml"
+ workflow_dispatch:
+
+permissions: {}
+
+env:
+ DEBUG: ${{ github.ref_type != 'tag' }}
+
+jobs:
+ build:
+ name: Build (${{ matrix.system }})
+
+ permissions:
+ contents: read
+
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - os: ubuntu-22.04
+ system: x86_64-linux
+
+ - os: ubuntu-22.04-arm
+ system: aarch64-linux
+
+ - os: macos-14
+ system: aarch64-darwin
+
+ runs-on: ${{ matrix.os }}
+
+ defaults:
+ run:
+ working-directory: meshmc
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ - name: Install Nix
+ uses: cachix/install-nix-action@v31
+
+ - name: Setup Nix Magic Cache
+ if: ${{ github.event_name == 'pull_request' }}
+ uses: DeterminateSystems/magic-nix-cache-action@v13
+ with:
+ diagnostic-endpoint: ""
+ use-flakehub: false
+
+ - name: Setup Cachix
+ if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
+ uses: cachix/cachix-action@v17
+ with:
+ name: meshmc
+ authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
+
+ - name: Run Flake checks
+ run: |
+ nix flake check --print-build-logs --show-trace
+
+ - name: Build debug package
+ if: ${{ env.DEBUG == 'true' }}
+ run: |
+ nix build \
+ --no-link --print-build-logs --print-out-paths \
+ .#meshmc-debug >> "$GITHUB_STEP_SUMMARY"
+
+ - name: Build release package
+ if: ${{ env.DEBUG == 'false' }}
+ env:
+ TAG: ${{ github.ref_name }}
+ SYSTEM: ${{ matrix.system }}
+ run: |
+ nix build --no-link --print-out-paths .#meshmc \
+ | tee -a "$GITHUB_STEP_SUMMARY" \
+ | xargs cachix pin meshmc "$TAG"-"$SYSTEM"
diff --git a/.github/workflows/meshmc-publish.yml b/.github/workflows/meshmc-publish.yml
new file mode 100644
index 0000000000..d0ce9948d7
--- /dev/null
+++ b/.github/workflows/meshmc-publish.yml
@@ -0,0 +1,25 @@
+name: "MeshMC: Publish"
+
+on:
+ release:
+ types: [released]
+
+permissions: {}
+
+jobs:
+ winget:
+ name: Winget
+
+ permissions:
+ contents: read
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Publish on Winget
+ uses: vedantmgoyal2009/winget-releaser@v2
+ with:
+ identifier: ProjectTick.MeshMC
+ version: ${{ github.event.release.tag_name }}
+ installers-regex: 'MeshMC-Windows-MSVC(:?-arm64|-Legacy)?-Setup-.+\.exe$'
+ token: ${{ secrets.WINGET_TOKEN }}
diff --git a/.github/workflows/meshmc-release.yml b/.github/workflows/meshmc-release.yml
new file mode 100644
index 0000000000..9a50e9ca73
--- /dev/null
+++ b/.github/workflows/meshmc-release.yml
@@ -0,0 +1,124 @@
+name: "MeshMC: Release"
+
+on:
+ push:
+ tags:
+ - "*"
+
+permissions: {}
+
+jobs:
+ build_release:
+ name: Build Release
+ uses: ./.github/workflows/meshmc-build.yml
+ permissions:
+ contents: read
+ id-token: write
+ packages: write
+ with:
+ build-type: Release
+ environment: Release
+ secrets: inherit
+
+ create_release:
+ needs: build_release
+ permissions:
+ contents: write
+ runs-on: ubuntu-latest
+ outputs:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ submodules: "true"
+ path: "MeshMC-source"
+ - name: Download artifacts
+ uses: actions/download-artifact@v8
+ - name: Grab and store version
+ run: |
+ tag_name=$(echo ${{ github.ref }} | grep -oE "[^/]+$")
+ echo "VERSION=$tag_name" >> $GITHUB_ENV
+ - name: Package artifacts properly
+ run: |
+ mv ${{ github.workspace }}/MeshMC-source MeshMC-${{ env.VERSION }}
+ mv MeshMC-Linux-Qt6-Portable*/MeshMC-portable.tar.gz MeshMC-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
+ mv MeshMC-Linux-aarch64-Qt6-Portable*/MeshMC-portable.tar.gz MeshMC-Linux-aarch64-Qt6-Portable-${{ env.VERSION }}.tar.gz
+ mv MeshMC-*.AppImage/MeshMC-*-x86_64.AppImage MeshMC-Linux-x86_64.AppImage
+ mv MeshMC-*.AppImage.zsync/MeshMC-*-x86_64.AppImage.zsync MeshMC-Linux-x86_64.AppImage.zsync
+ mv MeshMC-*.AppImage/MeshMC-*-aarch64.AppImage MeshMC-Linux-aarch64.AppImage
+ mv MeshMC-*.AppImage.zsync/MeshMC-*-aarch64.AppImage.zsync MeshMC-Linux-aarch64.AppImage.zsync
+ mv MeshMC-macOS*/MeshMC.zip MeshMC-macOS-${{ env.VERSION }}.zip
+ mv MeshMC-macOS*/MeshMC.dmg MeshMC-macOS-${{ env.VERSION }}.dmg
+
+ tar --exclude='.git' -czf MeshMC-${{ env.VERSION }}.tar.gz MeshMC-${{ env.VERSION }}
+
+ for d in MeshMC-Windows-MSVC*; do
+ cd "${d}" || continue
+ LEGACY="$(echo -n ${d} | grep -o Legacy || true)"
+ ARM64="$(echo -n ${d} | grep -o arm64 || true)"
+ INST="$(echo -n ${d} | grep -o Setup || true)"
+ PORT="$(echo -n ${d} | grep -o Portable || true)"
+ NAME="MeshMC-Windows-MSVC"
+ test -z "${LEGACY}" || NAME="${NAME}-Legacy"
+ test -z "${ARM64}" || NAME="${NAME}-arm64"
+ test -z "${PORT}" || NAME="${NAME}-Portable"
+ test -z "${INST}" || mv MeshMC-*.exe ../${NAME}-Setup-${{ env.VERSION }}.exe
+ test -n "${INST}" || zip -r -9 "../${NAME}-${{ env.VERSION }}.zip" *
+ cd ..
+ done
+
+ for d in MeshMC-Windows-MinGW-w64*; do
+ cd "${d}" || continue
+ INST="$(echo -n ${d} | grep -o Setup || true)"
+ PORT="$(echo -n ${d} | grep -o Portable || true)"
+ NAME="MeshMC-Windows-MinGW-w64"
+ test -z "${PORT}" || NAME="${NAME}-Portable"
+ test -z "${INST}" || mv MeshMC-*.exe ../${NAME}-Setup-${{ env.VERSION }}.exe
+ test -n "${INST}" || zip -r -9 "../${NAME}-${{ env.VERSION }}.zip" *
+ cd ..
+ done
+
+ for d in MeshMC-Windows-MinGW-arm64*; do
+ cd "${d}" || continue
+ INST="$(echo -n ${d} | grep -o Setup || true)"
+ PORT="$(echo -n ${d} | grep -o Portable || true)"
+ NAME="MeshMC-Windows-MinGW-arm64"
+ test -z "${PORT}" || NAME="${NAME}-Portable"
+ test -z "${INST}" || mv MeshMC-*.exe ../${NAME}-Setup-${{ env.VERSION }}.exe
+ test -n "${INST}" || zip -r -9 "../${NAME}-${{ env.VERSION }}.zip" *
+ cd ..
+ done
+
+ - name: Create release
+ id: create_release
+ uses: softprops/action-gh-release@v2
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ tag_name: ${{ github.ref }}
+ name: MeshMC ${{ env.VERSION }}
+ draft: true
+ prerelease: false
+ fail_on_unmatched_files: true
+ files: |
+ MeshMC-Linux-x86_64.AppImage
+ MeshMC-Linux-x86_64.AppImage.zsync
+ MeshMC-Linux-aarch64.AppImage
+ MeshMC-Linux-aarch64.AppImage.zsync
+ MeshMC-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
+ MeshMC-Linux-aarch64-Qt6-Portable-${{ env.VERSION }}.tar.gz
+ MeshMC-Windows-MinGW-w64-${{ env.VERSION }}.zip
+ MeshMC-Windows-MinGW-w64-Portable-${{ env.VERSION }}.zip
+ MeshMC-Windows-MinGW-w64-Setup-${{ env.VERSION }}.exe
+ MeshMC-Windows-MinGW-arm64-${{ env.VERSION }}.zip
+ MeshMC-Windows-MinGW-arm64-Portable-${{ env.VERSION }}.zip
+ MeshMC-Windows-MinGW-arm64-Setup-${{ env.VERSION }}.exe
+ MeshMC-Windows-MSVC-arm64-${{ env.VERSION }}.zip
+ MeshMC-Windows-MSVC-arm64-Portable-${{ env.VERSION }}.zip
+ MeshMC-Windows-MSVC-arm64-Setup-${{ env.VERSION }}.exe
+ MeshMC-Windows-MSVC-${{ env.VERSION }}.zip
+ MeshMC-Windows-MSVC-Portable-${{ env.VERSION }}.zip
+ MeshMC-Windows-MSVC-Setup-${{ env.VERSION }}.exe
+ MeshMC-macOS-${{ env.VERSION }}.zip
+ MeshMC-macOS-${{ env.VERSION }}.dmg
+ MeshMC-${{ env.VERSION }}.tar.gz
diff --git a/.github/workflows/tomlplusplus-ci.yml b/.github/workflows/tomlplusplus-ci.yml
new file mode 100644
index 0000000000..974601fdf9
--- /dev/null
+++ b/.github/workflows/tomlplusplus-ci.yml
@@ -0,0 +1,146 @@
+name: "tomlplusplus: CI"
+
+on:
+ push:
+ paths:
+ - "tomlplusplus/**.h"
+ - "tomlplusplus/**.hpp"
+ - "tomlplusplus/**.cpp"
+ - "tomlplusplus/**.inl"
+ - "tomlplusplus/**.py"
+ - "tomlplusplus/**/meson.build"
+ - ".github/workflows/tomlplusplus-ci.yml"
+ pull_request:
+ paths:
+ - "tomlplusplus/**.h"
+ - "tomlplusplus/**.hpp"
+ - "tomlplusplus/**.cpp"
+ - "tomlplusplus/**.inl"
+ - "tomlplusplus/**.py"
+ - "tomlplusplus/**/meson.build"
+ - ".github/workflows/tomlplusplus-ci.yml"
+ workflow_dispatch:
+
+concurrency:
+ group: tomlplusplus-${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+env:
+ clang_version: "14"
+ gcc_version: "11"
+
+jobs:
+ linux:
+ strategy:
+ fail-fast: false
+ matrix:
+ compiler:
+ - "clang"
+ - "gcc"
+ linker:
+ - "lld"
+ type:
+ - "debug"
+ - "release"
+
+ runs-on: ubuntu-latest
+
+ defaults:
+ run:
+ shell: bash
+ working-directory: tomlplusplus
+
+ steps:
+ - name: Install base dependencies
+ run: |
+ sudo apt -y update
+ sudo apt -y install --no-install-recommends git ninja-build libstdc++-${{ env.gcc_version }}-dev locales-all
+
+ - uses: actions/checkout@v6
+
+ - name: Install python dependencies
+ run: |
+ pip3 install --user --no-cache-dir --upgrade meson
+ pip3 install --user --no-cache-dir --upgrade -r tools/requirements.txt
+
+ - name: Check toml.hpp
+ run: |
+ cd tools
+ python3 ci_single_header_check.py
+
+ - name: Install lld
+ if: ${{ startsWith(matrix.linker, 'lld') }}
+ run: |
+ sudo apt -y install --no-install-recommends lld-${{ env.clang_version }}
+ sudo update-alternatives --install /usr/bin/ld.lld ld.lld /usr/bin/ld.lld-${{ env.clang_version }} 1000
+
+ - name: Install clang
+ if: ${{ startsWith(matrix.compiler, 'clang') }}
+ run: |
+ sudo apt -y install --no-install-recommends clang-${{ env.clang_version }}
+ sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-${{ env.clang_version }} 1000
+ sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-${{ env.clang_version }} 1000
+
+ - name: Install gcc
+ if: ${{ startsWith(matrix.compiler, 'gcc') }}
+ run: |
+ sudo apt -y install --no-install-recommends gcc-${{ env.gcc_version }} g++-${{ env.gcc_version }}
+ sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-${{ env.gcc_version }} 1000
+ sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-${{ env.gcc_version }} 1000
+
+ - name: Configure locales
+ run: |
+ sudo locale-gen 'en_US.utf8' 'ja_JP.utf8' 'de_DE.utf8' 'it_IT.utf8' 'tr_TR.utf8' 'fi_FI.utf8' 'fr_FR.utf8' 'zh_CN.utf8'
+
+ - name: Configure Meson
+ run: |
+ CXX=c++ CXX_LD=${{ matrix.linker }} meson setup build --buildtype=${{ matrix.type }} -Ddevel=true -Db_lto=false
+
+ - name: Build
+ run: meson compile -C build
+
+ - name: Test
+ run: meson test -C build --verbose
+
+ windows:
+ strategy:
+ fail-fast: false
+ matrix:
+ type:
+ - "debug"
+ - "release"
+ permissive:
+ - false
+ - true
+ arch:
+ - name: "x64"
+ runner: "windows-2022"
+ - name: "arm64"
+ runner: "windows-11-arm"
+ runs-on: ${{ matrix.arch.runner }}
+
+ defaults:
+ run:
+ shell: cmd
+ working-directory: tomlplusplus
+
+ steps:
+ - name: Install dependencies
+ run: |
+ python3 -m pip install -U pip
+ pip3 install meson ninja
+
+ - uses: actions/checkout@v6
+
+ - uses: ilammy/msvc-dev-cmd@v1
+ with:
+ arch: ${{ matrix.arch.name }}
+
+ - name: Configure Meson
+ run: meson setup build --vsenv --buildtype=${{ matrix.type }} -Ddevel=true -Db_lto=false -Dpermissive=${{ matrix.permissive }}
+
+ - name: Build
+ run: meson compile -C build
+
+ - name: Test
+ run: meson test -C build --verbose
diff --git a/.github/workflows/uvim-ci.yml b/.github/workflows/uvim-ci.yml
new file mode 100644
index 0000000000..a94ac0c3c1
--- /dev/null
+++ b/.github/workflows/uvim-ci.yml
@@ -0,0 +1,180 @@
+name: "uvim: CI"
+
+on:
+ push:
+ branches: ['**']
+ paths:
+ - 'uvim/**'
+ - '.github/workflows/uvim-ci.yml'
+ - '.github/actions/uvim/**'
+ pull_request:
+ paths:
+ - 'uvim/**'
+ - '.github/workflows/uvim-ci.yml'
+ - '.github/actions/uvim/**'
+
+concurrency:
+ group: uvim-${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+
+jobs:
+ linux:
+ runs-on: ${{ matrix.architecture == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
+
+ env:
+ CC: ${{ matrix.compiler }}
+ GCC_VER: 14
+ CLANG_VER: 21
+ TEST: test
+ SRCDIR: ./src
+ LEAK_CFLAGS: -DEXITFREE
+ LOG_DIR: ${{ github.workspace }}/logs
+ TERM: xterm
+ DISPLAY: ':99'
+ DEBIAN_FRONTEND: noninteractive
+
+ strategy:
+ fail-fast: false
+ matrix:
+ features: [tiny, normal, huge]
+ compiler: [clang, gcc]
+ extra: [[]]
+ architecture: [native]
+ include:
+ - features: tiny
+ compiler: clang
+ extra: [nogui]
+ - features: tiny
+ compiler: gcc
+ extra: [nogui]
+ - features: tiny
+ compiler: gcc
+ extra: [nogui]
+ architecture: arm64
+ - features: huge
+ coverage: true
+ - features: huge
+ compiler: clang
+ interface: dynamic
+ python3: stable-abi
+ - features: huge
+ compiler: gcc
+ coverage: true
+ interface: dynamic
+ extra: [uchar, testgui]
+ - features: huge
+ compiler: gcc
+ coverage: true
+ extra: [unittests]
+ - features: huge
+ compiler: gcc
+ coverage: true
+ extra: [unittests]
+ architecture: arm64
+ - features: normal
+ compiler: gcc
+ extra: [vimtags, proto, codestyle]
+
+ defaults:
+ run:
+ working-directory: uvim
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ - name: Install dependencies
+ run: |
+ sudo apt-get update && sudo apt-get install -y \
+ autoconf \
+ clang \
+ lcov \
+ gettext \
+ libcanberra-dev \
+ libperl-dev \
+ python3-dev \
+ liblua5.4-dev \
+ lua5.4 \
+ ruby-dev \
+ tcl-dev \
+ libsodium-dev \
+ libgtk-3-dev \
+ desktop-file-utils \
+ libtool-bin
+
+ - name: Build
+ run: |
+ if [ "${{ matrix.features }}" = "tiny" ]; then
+ ./configure --with-features=tiny --disable-gui
+ elif [ "${{ matrix.features }}" = "normal" ]; then
+ ./configure --with-features=normal --disable-gui
+ else
+ ./configure --with-features=huge \
+ --enable-perlinterp \
+ --enable-pythoninterp \
+ --enable-python3interp \
+ --enable-rubyinterp \
+ --enable-luainterp \
+ --enable-tclinterp \
+ --enable-gui=gtk3
+ fi
+ make -j$(nproc)
+
+ - name: Test
+ timeout-minutes: 25
+ run: |
+ make $TEST
+
+ - name: Upload test artifacts
+ if: failure()
+ uses: ./.github/actions/uvim/test_artifacts
+
+ macos:
+ runs-on: ${{ matrix.runner }}
+
+ env:
+ CC: clang
+ TEST: test
+ SRCDIR: ./src
+ LEAK_CFLAGS: -DEXITFREE
+ TERM: xterm
+
+ strategy:
+ fail-fast: false
+ matrix:
+ features: [tiny, normal, huge]
+ runner: [macos-15]
+
+ defaults:
+ run:
+ working-directory: uvim
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ - name: Install dependencies
+ run: brew install lua
+
+ - name: Build
+ run: |
+ if [ "${{ matrix.features }}" = "tiny" ]; then
+ ./configure --with-features=tiny --disable-gui
+ elif [ "${{ matrix.features }}" = "normal" ]; then
+ ./configure --with-features=normal --disable-gui
+ else
+ ./configure --with-features=huge \
+ --enable-python3interp \
+ --enable-rubyinterp \
+ --enable-luainterp \
+ --enable-tclinterp
+ fi
+ make -j$(sysctl -n hw.logicalcpu)
+
+ - name: Test
+ timeout-minutes: 25
+ run: |
+ make $TEST