Initial commit of mtgonline project
This commit is contained in:
Vendored
+509
@@ -0,0 +1,509 @@
|
||||
<!--! @page contributing Contributing -->
|
||||
|
||||
[Introduction](#contributing-to-cockatrice) | [Code Style Guide](
|
||||
#code-style-guide) | [Translations](#translations) | [Release Management](
|
||||
#release-management)
|
||||
|
||||
----
|
||||
|
||||
<br>
|
||||
|
||||
# Contributing to Cockatrice #
|
||||
|
||||
First off, thanks for taking the time and considering to lend a helping hand to our project! 🎉 ❤ ️✨
|
||||
|
||||
> [!NOTE]
|
||||
> The following is a set of guidelines for contributing to Cockatrice.
|
||||
> These are mostly guidelines, not rules. Use your best judgment, and feel free to
|
||||
> propose changes to this document in a pull request.
|
||||
>
|
||||
> [](
|
||||
> https://discord.gg/3Z9yzmA)
|
||||
> If you'd like to ask questions, get advice, or just want to say "Hi",
|
||||
> the Cockatrice Development Team uses [Discord](https://discord.gg/ZASRzKu)
|
||||
> for communications and you can reach out in the `#dev` channel.
|
||||
|
||||
|
||||
# Recommended Setups #
|
||||
|
||||
For those developers on **Linux** or **macOS** environment, many of our
|
||||
developers like working with a nifty program called [CLion](
|
||||
https://www.jetbrains.com/clion/). The program is a great asset and one of the
|
||||
best tools you'll find on these systems.
|
||||
|
||||
Developers on **Windows** systems tend to find [Visual Studio](
|
||||
https://www.visualstudio.com/) the best tool for the job.
|
||||
|
||||
But you're welcomed to use any IDE you enjoy most of course!
|
||||
|
||||
|
||||
# Code Style Guide #
|
||||
|
||||
### Formatting and continuous integration (CI) ###
|
||||
|
||||
We use a separate job on the CI to check your code for formatting issues. If
|
||||
your pull request failed the test, you can check the output on the checks tab.
|
||||
It's the first job called "linter", you can click the "Check code formatting"
|
||||
step to see the output of the test.
|
||||
|
||||
The message will look like this:
|
||||
```
|
||||
***********************************************************
|
||||
*** ***
|
||||
*** Your code does not comply with our style guide. ***
|
||||
*** ***
|
||||
*** Please correct it or run the "format.sh" script. ***
|
||||
*** Then commit and push those changes to this branch. ***
|
||||
*** Check our CONTRIBUTING.md file for more details. ***
|
||||
*** ***
|
||||
*** Thank you ❤️ ***
|
||||
*** ***
|
||||
***********************************************************
|
||||
```
|
||||
The CONTRIBUTING.md file mentioned in that message is the file you are
|
||||
currently reading. Please see [this section](#formatting) below for full
|
||||
information on our formatting guidelines.
|
||||
|
||||
### Compatibility ###
|
||||
|
||||
Cockatrice is currently compiled on all platforms using <kbd>C++20</kbd>.
|
||||
You'll notice <kbd>C++03</kbd> code throughout the codebase. Please feel free
|
||||
to help convert it over!
|
||||
|
||||
For consistency, we use Qt data structures where possible. For example,
|
||||
`QString` over `std::string` and `QList` over `std::vector`.
|
||||
|
||||
Do not use old C style casts in new code, instead use a [`static_cast<>`](
|
||||
https://en.cppreference.com/w/cpp/language/static_cast)
|
||||
or other appropriate conversion.
|
||||
|
||||
### Formatting ###
|
||||
|
||||
The handy tool `clang-format` can format your code for you, it is available for
|
||||
almost any environment. A special [`.clang-format`](
|
||||
https://github.com/Cockatrice/Cockatrice/blob/master/.clang-format) configuration file is
|
||||
included in the project and is used to format your code.
|
||||
|
||||
We've also included a bash script, `format.sh`, that will use clang-format to
|
||||
format all files in your PR in one go. Use `./format.sh --help` to show a full
|
||||
help page.
|
||||
|
||||
To run clang-format on a single source file simply use the command
|
||||
`clang-format -i <filename>` to format it in place. (Some systems install
|
||||
clang-format with a specific version number appended,
|
||||
`find /usr/bin -name clang-format*` should find it for you)
|
||||
|
||||
See the [clang-format documentation](
|
||||
https://clang.llvm.org/docs/ClangFormat.html) for more information about the tool.
|
||||
|
||||
#### Header Files ####
|
||||
|
||||
Use header files with the extension `.h` and source files with the extension
|
||||
`.cpp`.
|
||||
|
||||
Use header guards in the form of `FILE_NAME_H`.
|
||||
|
||||
Simple functions, such as getters, may be written inline in the header file,
|
||||
but other functions should be written in the source file.
|
||||
|
||||
Group project includes first, followed by library includes. All in alphabetic order.
|
||||
Like this:
|
||||
```c++
|
||||
// Good
|
||||
#include "card.h"
|
||||
#include "deck.h"
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
// Bad
|
||||
#include <QList>
|
||||
#include "card.h"
|
||||
#include <QString>
|
||||
#include "deck.h"
|
||||
|
||||
// Bad
|
||||
#include "card.h"
|
||||
#include "deck.h"
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
```
|
||||
|
||||
#### Naming ####
|
||||
|
||||
Use `UpperCamelCase` for classes, structs, enums, etc. and `lowerCamelCase` for
|
||||
function and variable names.
|
||||
|
||||
Don't use [Hungarian Notation](
|
||||
https://en.wikipedia.org/wiki/Hungarian_notation).
|
||||
|
||||
Member variables aren't decorated in any way. Don't prefix or suffix them with
|
||||
underscores, etc.
|
||||
|
||||
Use a separate line for each declaration, don't use a single line like this
|
||||
`int one = 1, two = 2` and instead split them into two lines.
|
||||
|
||||
For arguments to constructors which have the same names as member variables,
|
||||
prefix those arguments with underscores:
|
||||
```c++
|
||||
MyClass::MyClass(int _myData) : myData(_myData)
|
||||
{
|
||||
|
||||
}
|
||||
```
|
||||
Pointers and references should be denoted with the `*` or `&` going with the
|
||||
variable name:
|
||||
```c++
|
||||
// Good
|
||||
Foo *foo1 = new Foo;
|
||||
Foo &foo2 = *foo1;
|
||||
|
||||
// Bad
|
||||
Bar* bar1 = new Bar;
|
||||
Bar& bar2 = *bar1;
|
||||
```
|
||||
Use `nullptr` instead of `NULL` (or `0`) for null pointers.
|
||||
If you find any usage of the old keywords, we encourage you to fix it.
|
||||
|
||||
#### Braces ####
|
||||
|
||||
Braces should go on their own line except for control statements, the use of
|
||||
braces around single line statements is preferred.
|
||||
See the following example:
|
||||
```c++
|
||||
int main()
|
||||
{ // function or class: own line
|
||||
if (someCondition) { // control statement: same line
|
||||
doSomething(); // single line statement, braces preferred
|
||||
} else if (someOtherCondition1) { // else goes on the same line as a closing brace
|
||||
for (int i = 0; i < 100; i++) {
|
||||
doSomethingElse();
|
||||
}
|
||||
} else {
|
||||
while (someOtherCondition2) {
|
||||
doSomethingElse();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Indentation and Spacing ####
|
||||
|
||||
Always indent using 4 spaces, do not use tabs. Opening and closing braces
|
||||
should be on the same indentation layer, member access specifiers in classes or
|
||||
structs should not be indented.
|
||||
|
||||
All operators and braces should be separated by spaces, do not add a space next
|
||||
to the inside of a brace.
|
||||
|
||||
If multiple lines of code that follow eachother have single line comments
|
||||
behind them, place all of them on the same indentation level. This indentation
|
||||
level should be equal to the longest line of code for each of these comments,
|
||||
without added spacing.
|
||||
|
||||
#### Lines ####
|
||||
|
||||
Do not leave trailing whitespace on any line. Most IDEs check for this
|
||||
nowadays and clean it up for you.
|
||||
|
||||
Lines should be 120 characters or less. Please break up lines that are too long
|
||||
into smaller parts, for example at spaces or after opening a brace.
|
||||
|
||||
### Documentation Comments ###
|
||||
|
||||
Use [Doxygen](https://www.doxygen.nl/) for code documentation:
|
||||
|
||||
- **Doc blocks**: Use `/** @brief Description */` (Javadoc-style), not `///`
|
||||
- **Member comments**: Use trailing `///<` for inline member documentation
|
||||
- **TODOs**: Use `//! \todo Description` (Qt-style), Doxygen collects them into a Todo List
|
||||
(uses [Qt-style comments](https://www.doxygen.nl/manual/docblocks.html) with
|
||||
Doxygen's [\todo command](https://www.doxygen.nl/manual/commands.html#cmdtodo))
|
||||
|
||||
### Memory Management ###
|
||||
|
||||
New code should be written using references over pointers and stack allocation
|
||||
over heap allocation wherever possible.
|
||||
```c++
|
||||
// Good: uses stack allocation and references
|
||||
void showCard(const Card &card);
|
||||
int main()
|
||||
{
|
||||
Card card;
|
||||
showCard(card);
|
||||
}
|
||||
|
||||
// Bad: relies on manual memory management and doesn't give us much
|
||||
// null-safety.
|
||||
void showCard(const Card *card);
|
||||
int main()
|
||||
{
|
||||
Card *card = new Card;
|
||||
showCard(card);
|
||||
delete card;
|
||||
}
|
||||
```
|
||||
(Remember to pass by `const` reference wherever possible, to avoid accidentally
|
||||
mutating objects.)
|
||||
|
||||
When pointers can't be avoided, try to use a smart pointer of some sort, such
|
||||
as `QScopedPointer`, or, less preferably, `QSharedPointer`.
|
||||
|
||||
### Database Migrations ###
|
||||
|
||||
The servatrice database's schema can be found at `servatrice/servatrice.sql`.
|
||||
Everytime the schema gets modified, some other steps are due:
|
||||
1. Increment the value of `cockatrice_schema_version` in `servatrice.sql`;
|
||||
2. Increment the value of `DATABASE_SCHEMA_VERSION` in
|
||||
`servatrice_database_interface.h` accordingly;
|
||||
3. Create a new migration file inside the `servatrice/migrations` directory
|
||||
named after the new schema version.
|
||||
4. Run the `servatrice/check_schema_version.sh` script to ensure everything is
|
||||
fine.
|
||||
|
||||
The migration file should include the sql statements needed to migrate the
|
||||
database schema and data from the previous to the new version, and an
|
||||
additional statement that updates `cockatrice_schema_version` to the correct
|
||||
value.
|
||||
|
||||
Ensure that the migration produces the expected effects; e.g. if you add a
|
||||
new column, make sure the migration places it in the same order as
|
||||
servatrice.sql.
|
||||
|
||||
### Protocol Buffer ###
|
||||
|
||||
Cockatrice and Servatrice exchange data using binary messages. The syntax of
|
||||
these messages is defined in the `proto` files in the `common/pb` folder. These
|
||||
files define the way data contained in each message is serialized using
|
||||
Google's [protocol buffers](https://developers.google.com/protocol-buffers/).
|
||||
Any change to the `proto` files should be taken with caution and tested
|
||||
intensively before being merged, because a change to the protocol could make
|
||||
new clients incompatible to the old server and vice versa.
|
||||
|
||||
You can find more information on how we use Protobuf on [our wiki!](
|
||||
https://github.com/Cockatrice/Cockatrice/wiki/Client-server-protocol)
|
||||
|
||||
|
||||
# Reviewing Pull Requests #
|
||||
|
||||
After you have finished your changes to the project you should put them on a
|
||||
separate branch of your fork on GitHub and open a [pull request](
|
||||
https://docs.github.com/en/free-pro-team@latest/desktop/contributing-and-collaborating-using-github-desktop/creating-an-issue-or-pull-request
|
||||
).
|
||||
Your code will then be automatically compiled by GitHub actions for Linux and
|
||||
macOS, and by Appveyor for Windows. Additionally GitHub will perform a [Linting
|
||||
check](#formatting-and-continuous-integration-ci). If any issues come up you
|
||||
can check their status at the bottom of the pull request page, click on details
|
||||
to go to the CI website and see the different build logs.
|
||||
|
||||
If your pull request passes our tests and has no merge conflicts, it will be
|
||||
reviewed by our team members. You can then address any requested changes. When
|
||||
all changes have been approved your pull request will be squashed into a single
|
||||
commit and merged into the master branch by a team member. Your change will then
|
||||
be included in the next release 👍
|
||||
|
||||
|
||||
# Translations #
|
||||
|
||||
Basic workflow for translations:
|
||||
1. Developer adds a `tr("foo")` string in the code;
|
||||
2. CI updates the `*_en@source.ts files` regularly and creates a PR automatically;
|
||||
3. Maintainer verifies and merges the change;
|
||||
4. Transifex picks up the new files from GitHub automatically;
|
||||
5. Translators translate the new untranslated strings on Transifex;
|
||||
6. Before a release, a maintainer fetches the newest translations from Transifex.
|
||||
|
||||
### Using Translations (for developers) ###
|
||||
|
||||
All user interface strings inside Cockatrice's source code must be written
|
||||
in English (US).
|
||||
Translations to other languages are managed using [Transifex](
|
||||
https://transifex.com/cockatrice/cockatrice/).
|
||||
|
||||
Adding a new string for translation is as easy as adding the string in the
|
||||
`tr("")` function, the string will be picked up as translatable automatically
|
||||
and translated as needed.
|
||||
For example, setting the text of a label in the way that the string
|
||||
`"My name is:"` can be translated:
|
||||
```c++
|
||||
nameLabel.setText(tr("My name is:"));
|
||||
```
|
||||
|
||||
To translate a string that would have plural forms you can add the amount to
|
||||
the tr() call, also you can add an extra string as a hint for translators:
|
||||
```c++
|
||||
QString message = tr("Everyone draws %n cards", "english hint for translators", amount);
|
||||
```
|
||||
See [Qt's wiki on translations](
|
||||
https://doc.qt.io/qt-5/i18n-source-translation.html#handling-plurals)
|
||||
|
||||
If you're about to propose a change that adds or modifies any translatable
|
||||
string in the code, you don't need to take care of adding the new strings to
|
||||
the translation files.<br>
|
||||
We have an automated process to update our language source files on a schedule
|
||||
and provide the translators on Transifex with the new contents.<br>
|
||||
Maintainers can also manually trigger this workflow on demand via GitHub Actions.
|
||||
|
||||
### Maintaining Translations (for maintainers) ###
|
||||
|
||||
When new translatable strings have been added to the code, a maintainer has to
|
||||
make them available to translators on Transifex.
|
||||
|
||||
To help with that, we have an automated CI workflow, that regularly looks at the
|
||||
code in the master branch, extracts all strings and updates dedicated source string
|
||||
files with any changes. These updates are not commited right away, the CI creates a
|
||||
PR for reviewing instead.<br>
|
||||
After approval, our translation tool automatically picks the changes up and deploys
|
||||
them to our translators. Be mindful when merging only a few changes!
|
||||
|
||||
Once a release is planned, or when a lot of strings have been added or changed, a
|
||||
maintainer can manually trigger a CI run to extract all strings on demand.
|
||||
|
||||
<details>
|
||||
<summary><b>Manually trigger CI run (Workflow Dispatch)</b></summary>
|
||||
|
||||
Maintainers can always request the CI to run on demand if it's required.
|
||||
|
||||
Go to the `Actions` tab and select our dedicated translation workflow:
|
||||
https://github.com/Cockatrice/Cockatrice/actions/workflows/translations.yml
|
||||
|
||||
You see a "This workflow has a workflow_dispatch event trigger." hint at the top of
|
||||
the list.<br>
|
||||
Select `Run workflow` on the right and trigger a run from master branch.
|
||||
|
||||
The CI will now check for changed strings and create a PR if there are any updates.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Manually update source strings locally</b></summary>
|
||||
|
||||
To update the english source files for translation, re-run cmake enabling the appropriate
|
||||
parameter and then run make:
|
||||
```sh
|
||||
cd cockatrice/build
|
||||
cmake .. -DUPDATE_TRANSLATIONS=ON
|
||||
make
|
||||
```
|
||||
If the parameter has been enabled correctly, when running "make" you should see
|
||||
a line similar to this one (the numbers may vary):
|
||||
```sh
|
||||
[ 76%] Generating ../../cockatrice/translations/cockatrice_en@source.ts
|
||||
Updating '../../cockatrice/translations/cockatrice_en@source.ts'...
|
||||
Found 857 source text(s) (8 new and 849 already existing)
|
||||
```
|
||||
You should then notice that the following files have uncommitted changes:
|
||||
|
||||
cockatrice/translations/cockatrice_en@source.ts
|
||||
oracle/translations/oracle_en@source.ts
|
||||
|
||||
It is recommended to disable the parameter afterwards using:
|
||||
```sh
|
||||
cmake .. -DUPDATE_TRANSLATIONS=OFF
|
||||
```
|
||||
Now you are ready to commit your changes and open a PR.
|
||||
|
||||
</details>
|
||||
|
||||
Once the changes get merged, Transifex will pick up the modified files
|
||||
automatically (checked every few hours) and update the web editor where
|
||||
translators will be able to translate the new strings right in the browser.
|
||||
|
||||
### Releasing Translations (for maintainers) ###
|
||||
|
||||
Before publishing a new release, a maintainer should fetch the most up to date
|
||||
translations from Transifex and commit them into the Cockatrice source code.
|
||||
We utilize the official GitHub integration to push all languages that are 100%
|
||||
translated from Transifex to our GitHub repo automatically.
|
||||
On top, it runs on a quarterly schedule to update changes for incomplete languages.
|
||||
A synchronisation/update can also be triggered manually from the Transifex web interface
|
||||
and a translation treshold can be set.
|
||||
|
||||
As an alternative, you can install the [Transifex CLI](https://developers.transifex.com/docs/cli).
|
||||
You'll then be able to use a git-like cli command to push and pull translations
|
||||
from Transifex to the source code and vice versa.
|
||||
|
||||
### Adding Translations (for translators) ###
|
||||
|
||||
As a translator, you can help to translate new strings on [Transifex](
|
||||
https://www.transifex.com/projects/p/cockatrice/) to your native language.
|
||||
Please have a look at the specific [FAQ for translators](
|
||||
https://github.com/Cockatrice/Cockatrice/wiki/Translation-FAQ).
|
||||
|
||||
|
||||
# Release Management #
|
||||
|
||||
### Publishing A New Release ###
|
||||
|
||||
We use [GitHub Releases](https://github.com/Cockatrice/Cockatrice/releases) to
|
||||
publish new stable versions and beta releases.
|
||||
Whenever a git tag is pushed to the repository, GitHub will create a draft
|
||||
release and upload binaries from our CI automatically.
|
||||
|
||||
To create a tag, simply do the following:
|
||||
```bash
|
||||
git checkout master
|
||||
git remote update -p
|
||||
git pull
|
||||
git tag $TAG_NAME
|
||||
git push $UPSTREAM $TAG_NAME
|
||||
```
|
||||
|
||||
You should define the variables as such:
|
||||
- `$UPSTREAM`: the remote for `git@github.com:Cockatrice/Cockatrice.git`
|
||||
- `$TAG_NAME` should be formatted as:
|
||||
- `YYYY-MM-DD-Release-MAJ.MIN.PATCH` for **stable releases**
|
||||
- `YYYY-MM-DD-Development-MAJ.MIN.PATCH-beta.X` for **beta releases**<br>
|
||||
With <kbd>MAJ</kbd>.<kbd>MIN</kbd>.<kbd>PATCH</kbd> being the NEXT release version!
|
||||
|
||||
This will cause a tagged release to be established on the GitHub repository,
|
||||
with the binaries being added to the release whenever they are done building in CI.
|
||||
The release is initially a draft, where the release notes can be edited and after
|
||||
all is checked and ready, it can be published as GitHub release.
|
||||
If you use a SemVer tag including "beta", the release that will be created at
|
||||
GitHub will be marked as a "Pre-release" automatically.
|
||||
The target of the `.../latest` URL will not be changed in that case, it always
|
||||
points to the latest stable release and not pre-releases/betas.
|
||||
|
||||
If you accidentally push a tag incorrectly (the tag is outdated, you didn't
|
||||
pull in the latest branch accidentally, you named the tag wrong, etc.) you can
|
||||
revoke the tag by doing the following:
|
||||
```bash
|
||||
git push --delete upstream $TAG_NAME
|
||||
git tag -d $TAG_NAME
|
||||
```
|
||||
You can also do this on GitHub.
|
||||
|
||||
> [!NOTE]
|
||||
> If you want to push a new release to replace it immediately with the same
|
||||
> name you have to delete the automatically created release first!
|
||||
|
||||
In the first lines of [CMakeLists.txt](
|
||||
https://github.com/Cockatrice/Cockatrice/blob/master/CMakeLists.txt)
|
||||
there's an hardcoded version number and pretty name used when compiling from
|
||||
master or custom (not tagged) versions.
|
||||
While on tagged versions these numbers are overridden by the version numbers
|
||||
coming from the tag title, it's good practice to increment the ones at CMake
|
||||
after every full release to stress that master is ahead of the last stable
|
||||
release.
|
||||
The preferred flow of operation is:
|
||||
- Just before a release, make sure the version number in CMakeLists.txt is set
|
||||
to the same release version you are about to tag.
|
||||
- This is also the time to change the pretty name in CMakeLists.txt called
|
||||
`GIT_TAG_RELEASENAME` and commit and push these changes.
|
||||
- Tag the release following the previously described syntax in order to get it
|
||||
correctly built and deployed by CI.
|
||||
- Wait for the configuration step to create the release and update the patch
|
||||
notes.
|
||||
- Check on the GitHub Actions page for build progress which should be the top
|
||||
listed [here](
|
||||
https://github.com/Cockatrice/Cockatrice/actions?query=event%3Apush+-branch%3Amaster
|
||||
).
|
||||
- When the build has been completed, you can verify if all uploaded files on the
|
||||
draft release are included and hit the publish button.
|
||||
- After the release is complete, update the CMake version number again to the
|
||||
next targeted beta version, typically increasing `PROJECT_VERSION_PATCH` by
|
||||
one.
|
||||
|
||||
When releasing a new stable version, all previous beta releases (and tags)
|
||||
should be deleted as well.
|
||||
This can be done the same way as revoking tags, mentioned above.
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [ZeldaZach]
|
||||
patreon: mtgjson
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: ["paypal.me/zachhalpern"]
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
---
|
||||
name: "🐛 Bug Report"
|
||||
about: Report an issue encountered while using Cockatrice
|
||||
title: ''
|
||||
type: 'Bug'
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- READ THIS BEFORE POSTING
|
||||
In Cockatrice, go to "Help" → "View Debug Log" and copy all information displayed at the
|
||||
top (above the separation line "----"), to below "System Information" section in this ticket!
|
||||
If you can't start Cockatrice to access these details, make
|
||||
sure to post your OS and the file name of the setup binary instead.
|
||||
-->
|
||||
|
||||
**System Information:**
|
||||
<!-- Read the hint above on where to find the important information to provide here! -->
|
||||
|
||||
|
||||
<details><summary>Debug Log:</summary>
|
||||
<!--
|
||||
In Cockatrice, go to "Help" → "View Debug Log", click the "Copy to clickboard" button and paste the output here.
|
||||
-->
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
_______________________________________________________________________________________
|
||||
|
||||
<!-- Explain your issue in detail here! Please attach screenshots if possible. -->
|
||||
|
||||
|
||||
|
||||
|
||||
_______________________________________________________________________________________
|
||||
|
||||
<!-- Describe the sequence of actions needed to experience the bug. -->
|
||||
|
||||
**Steps to reproduce:**
|
||||
- Do A
|
||||
- Do B
|
||||
- Do C ...
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 💬 Discord Community (Get help with server issues, e.g. Login)
|
||||
url: https://discord.com/invite/3Z9yzmA
|
||||
about: Need help with using the client? Want to find some games? Try the Discord server!
|
||||
- name: 🌐 Translations (Help improve the localization of the app)
|
||||
url: https://explore.transifex.com/cockatrice/cockatrice/
|
||||
# it is not possible to add a link to the wiki to this description
|
||||
about: For more information and guidance check our Translation FAQ on our wiki!
|
||||
- name: 📖 Code Documentation
|
||||
url: https://cockatrice.github.io/docs/
|
||||
about: Helpful source focusing on developers, but there are also references for users!
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
---
|
||||
name: "💡 Feature Request"
|
||||
about: Request a new feature for Cockatrice
|
||||
title: ''
|
||||
type: 'Feature'
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Please search the issue tracker for similar issues before posting!
|
||||
If your request is related to another request (but not the same!) list it here
|
||||
-->
|
||||
**Similar Requests**
|
||||
|
||||
|
||||
<!-- Describe your feature idea here in detail -->
|
||||
**Description of New Feature**
|
||||
|
||||
|
||||
<!-- If your feature requires some context, provide it here -->
|
||||
**Additional Context**
|
||||
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
## Related Ticket(s)
|
||||
- Fixes #IssueNumber
|
||||
|
||||
## Short roundup of the initial problem
|
||||
|
||||
|
||||
## What will change with this Pull Request?
|
||||
- this
|
||||
- and this
|
||||
|
||||
## Screenshots
|
||||
<!-- simply drag & drop image files directly into this description! -->
|
||||
Vendored
+41
@@ -0,0 +1,41 @@
|
||||
# Configuration options: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
# Enable version updates for git submodules
|
||||
# If SemVer is used, updates will happen to new releases only (not HEAD)
|
||||
# https://github.com/dependabot/dependabot-core/issues/1639
|
||||
# https://github.com/dependabot/dependabot-core/issues/2192
|
||||
- package-ecosystem: "gitsubmodule"
|
||||
# Look for `.gitmodules` in the `root` directory
|
||||
directory: "/"
|
||||
ignore:
|
||||
# Ignore updates for vcpkg (Bump to latest tag not working (no SemVer used)
|
||||
- dependency-name: "vcpkg"
|
||||
# Check for updates once a month
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
# Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
open-pull-requests-limit: 2
|
||||
|
||||
# # Enable version updates for Docker
|
||||
# Not yet possible to bump from one LTS version to the next and skip others, see:
|
||||
# https://github.com/dependabot/dependabot-core/issues/2247
|
||||
# - package-ecosystem: "docker"
|
||||
# # Look for a `Dockerfile` in the `root` directory
|
||||
# directory: "/"
|
||||
# # Check for updates once a week
|
||||
# schedule:
|
||||
# interval: "weekly"
|
||||
# # Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
# open-pull-requests-limit: 1
|
||||
|
||||
# Enable version updates for GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
# Directory must be set to "/" to check for workflow files in .github/workflows
|
||||
directory: "/"
|
||||
# Check for updates to GitHub Actions once a week
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
# Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
open-pull-requests-limit: 2
|
||||
+566
@@ -0,0 +1,566 @@
|
||||
name: Build Desktop
|
||||
|
||||
permissions:
|
||||
actions: write # needed to delete entries in GHA cache (update ccache)
|
||||
attestations: write # needed to persist the attestation.
|
||||
contents: write
|
||||
id-token: write # needed for signing certificate in attestation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '*/**' # matches all files not in root
|
||||
- '!**.md'
|
||||
- '!.github/**'
|
||||
- '!.tx/**'
|
||||
- '!doc/**'
|
||||
- '.github/workflows/desktop-build.yml'
|
||||
- 'CMakeLists.txt'
|
||||
- 'vcpkg.json'
|
||||
- 'vcpkg' # needed to match submodule bumps (gitlink)
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*/**' # matches all files not in root
|
||||
- '!**.md'
|
||||
- '!.github/**'
|
||||
- '!.tx/**'
|
||||
- '!doc/**'
|
||||
- '.github/workflows/desktop-build.yml'
|
||||
- 'CMakeLists.txt'
|
||||
- 'vcpkg.json'
|
||||
- 'vcpkg' # needed to match submodule bumps (gitlink)
|
||||
|
||||
# Cancel earlier, unfinished runs of this workflow on the same branch (unless on release)
|
||||
concurrency:
|
||||
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
|
||||
cancel-in-progress: ${{ github.ref_type != 'tag' }}
|
||||
|
||||
jobs:
|
||||
configure:
|
||||
name: Configure
|
||||
runs-on: ubuntu-slim
|
||||
outputs:
|
||||
tag: ${{ steps.configure.outputs.tag }}
|
||||
sha: ${{ steps.configure.outputs.sha }}
|
||||
|
||||
steps:
|
||||
- name: "Configure"
|
||||
env:
|
||||
RESOLVED_SHA: ${{ case(github.event_name == 'pull_request', github.event.pull_request.head.sha, github.sha) }}
|
||||
id: configure
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "$GITHUB_REF_TYPE" == 'tag' ]]; then # release
|
||||
echo "tag=$GITHUB_REF_NAME" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
echo "sha=$RESOLVED_SHA" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: "Checkout"
|
||||
if: steps.configure.outputs.tag != null
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0 # fetch all history for all branches and tags
|
||||
|
||||
- name: "Prepare release parameters"
|
||||
id: prepare
|
||||
if: steps.configure.outputs.tag != null
|
||||
shell: bash
|
||||
env:
|
||||
TAG: ${{ steps.configure.outputs.tag }}
|
||||
run: .ci/prep_release.sh
|
||||
|
||||
- name: "Create release"
|
||||
if: steps.configure.outputs.tag != null
|
||||
id: create_release
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
tag_name: ${{ steps.configure.outputs.tag }}
|
||||
target: ${{ steps.configure.outputs.sha }}
|
||||
release_name: ${{ steps.prepare.outputs.title }}
|
||||
body_path: ${{ steps.prepare.outputs.body_path }}
|
||||
prerelease: ${{ steps.prepare.outputs.is_beta }}
|
||||
run: |
|
||||
args=()
|
||||
[[ $prerelease == yes ]] && args+=(--prerelease)
|
||||
|
||||
gh release create "$tag_name" --verify-tag --draft "${args[@]}" \
|
||||
--target "$target" \
|
||||
--title "$release_name" \
|
||||
--notes-file "$body_path"
|
||||
|
||||
build-linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# The files in ".ci/$distro$version" correspond to the values given here
|
||||
include:
|
||||
- distro: Arch
|
||||
|
||||
allow-failure: yes
|
||||
package: skip # We are packaged in Arch already
|
||||
|
||||
- distro: Servatrice_Debian
|
||||
version: 12
|
||||
|
||||
package: DEB
|
||||
server_only: yes
|
||||
test: skip
|
||||
|
||||
- distro: Debian
|
||||
version: 12
|
||||
|
||||
package: DEB
|
||||
test: skip # Running tests on all distros is superfluous
|
||||
|
||||
- distro: Debian
|
||||
version: 13
|
||||
|
||||
package: DEB
|
||||
|
||||
- distro: Fedora
|
||||
version: 43
|
||||
|
||||
package: RPM
|
||||
test: skip # Running tests on all distros is superfluous
|
||||
|
||||
- distro: Fedora
|
||||
version: 44
|
||||
|
||||
package: RPM
|
||||
|
||||
- distro: Ubuntu
|
||||
version: 24.04
|
||||
|
||||
package: DEB
|
||||
test: skip # Running tests on all distros is superfluous
|
||||
|
||||
- distro: Ubuntu
|
||||
version: 26.04
|
||||
|
||||
package: DEB
|
||||
|
||||
name: ${{ matrix.distro }} ${{ matrix.version }}
|
||||
needs: configure
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: ${{ matrix.allow-failure == 'yes' }}
|
||||
timeout-minutes: 70
|
||||
env:
|
||||
CACHE: ${{ github.workspace }}/.cache/${{ matrix.distro }}${{ matrix.version }} # directory for caching docker image and ccache
|
||||
CCACHE_EVICTION_AGE: 7d
|
||||
CCACHE_SIZE: 550M # space of all repo is 10Gi: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy
|
||||
CMAKE_GENERATOR: 'Ninja'
|
||||
NAME: ${{ matrix.distro }}${{ matrix.version }}
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: "Restore compiler cache (ccache)"
|
||||
id: ccache_restore
|
||||
uses: actions/cache/restore@v6
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
|
||||
with:
|
||||
key: ccache-${{ matrix.distro }}${{ matrix.version }}-${{ env.BRANCH_NAME }}
|
||||
path: ${{ env.CACHE }}
|
||||
restore-keys: ccache-${{ matrix.distro }}${{ matrix.version }}-
|
||||
|
||||
- name: "Build ${{ matrix.distro }} ${{ matrix.version }} Docker image"
|
||||
shell: bash
|
||||
run: source .ci/docker.sh --build
|
||||
|
||||
- name: "Build debug and test"
|
||||
if: matrix.test != 'skip'
|
||||
shell: bash
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --debug --test --ccache "$CCACHE_SIZE" \
|
||||
--cmake-generator "$CMAKE_GENERATOR"
|
||||
|
||||
- name: "Build release package"
|
||||
id: build
|
||||
if: matrix.package != 'skip'
|
||||
shell: bash
|
||||
env:
|
||||
SUFFIX: '-${{ matrix.distro }}${{ matrix.version }}'
|
||||
package: '${{ matrix.package }}'
|
||||
server_only: '${{ matrix.server_only }}'
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
args=()
|
||||
[[ $server_only == yes ]] && args+=(--no-client)
|
||||
[[ $GITHUB_REF == "refs/heads/master" ]] && args+=(--evict-ccache "$CCACHE_EVICTION_AGE")
|
||||
args+=(--ccache "$CCACHE_SIZE")
|
||||
args+=(--cmake-generator "$CMAKE_GENERATOR")
|
||||
args+=(--suffix "$SUFFIX")
|
||||
|
||||
RUN --server --release --package "$package" "${args[@]}"
|
||||
|
||||
# Delete used cache to emulate a ccache update. See https://github.com/actions/cache/issues/342
|
||||
- name: "Delete remote compiler cache (ccache)"
|
||||
if: github.ref == 'refs/heads/master' && steps.ccache_restore.outputs.cache-hit
|
||||
continue-on-error: true
|
||||
env:
|
||||
CACHE_PRIMARY_KEY: ${{ steps.ccache_restore.outputs.cache-primary-key }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
if gh cache delete --repo "$GITHUB_REPOSITORY" "$CACHE_PRIMARY_KEY"; then
|
||||
echo "Cache deleted successfully"
|
||||
fi
|
||||
|
||||
- name: "Save updated compiler cache (ccache)"
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
key: ${{ steps.ccache_restore.outputs.cache-primary-key }}
|
||||
path: ${{ env.CACHE }}
|
||||
|
||||
- name: "Upload artifact"
|
||||
id: upload_artifact
|
||||
if: matrix.package != 'skip'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
archive: false
|
||||
if-no-files-found: error
|
||||
path: ${{ steps.build.outputs.path }}
|
||||
|
||||
- name: "Upload to release"
|
||||
id: upload_release
|
||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||
shell: bash
|
||||
env:
|
||||
asset_name: ${{ steps.build.outputs.fullname }}
|
||||
asset_path: ${{ steps.build.outputs.path }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
tag_name: ${{ needs.configure.outputs.tag }}
|
||||
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||
|
||||
- name: "Attest binary provenance"
|
||||
id: attestation
|
||||
if: steps.upload_release.outcome == 'success'
|
||||
uses: actions/attest@v4
|
||||
with:
|
||||
show-summary: false
|
||||
subject-path: ${{ steps.build.outputs.path }}
|
||||
|
||||
- name: "Verify binary attestation"
|
||||
if: steps.attestation.outcome == 'success'
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_PATH: ${{ steps.build.outputs.path }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: gh attestation verify "$BUILD_PATH" --repo Cockatrice/Cockatrice
|
||||
|
||||
build-vcpkg:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: macOS
|
||||
target: 13
|
||||
runner: macos-15-intel
|
||||
|
||||
ccache_eviction_age: 7d
|
||||
cmake_generator: Ninja
|
||||
make_package: 1
|
||||
override_target: 13
|
||||
package_suffix: "-macOS13_Intel"
|
||||
qt_version: 6.11.0
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
soc: Intel
|
||||
type: Release
|
||||
use_ccache: 1
|
||||
xcode: "16.4"
|
||||
|
||||
- os: macOS
|
||||
target: 14
|
||||
runner: macos-14
|
||||
|
||||
ccache_eviction_age: 7d
|
||||
cmake_generator: Ninja
|
||||
make_package: 1
|
||||
package_suffix: "-macOS14"
|
||||
qt_version: 6.11.0
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
soc: Apple
|
||||
type: Release
|
||||
use_ccache: 1
|
||||
xcode: "15.4"
|
||||
|
||||
- os: macOS
|
||||
target: 15
|
||||
runner: macos-15
|
||||
|
||||
ccache_eviction_age: 7d
|
||||
cmake_generator: Ninja
|
||||
make_package: 1
|
||||
package_suffix: "-macOS15"
|
||||
qt_version: 6.11.0
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
soc: Apple
|
||||
type: Release
|
||||
use_ccache: 1
|
||||
xcode: "16.4"
|
||||
|
||||
- os: macOS
|
||||
target: 15
|
||||
runner: macos-15
|
||||
|
||||
ccache_eviction_age: 7d
|
||||
cmake_generator: Ninja
|
||||
qt_version: 6.11.0
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
soc: Apple
|
||||
type: Debug
|
||||
use_ccache: 1
|
||||
xcode: "16.4"
|
||||
|
||||
- os: Windows
|
||||
target: 10
|
||||
runner: windows-2025
|
||||
|
||||
cmake_generator: "Visual Studio 18 2026"
|
||||
cmake_generator_platform: x64
|
||||
make_package: 1
|
||||
package_suffix: "-Win10"
|
||||
qt_version: 6.11.0
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
type: Release
|
||||
|
||||
name: ${{ matrix.os }} ${{ matrix.target }}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }}
|
||||
needs: configure
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 100
|
||||
env:
|
||||
CCACHE_DIR: ${{ github.workspace }}/.cache/
|
||||
CCACHE_SIZE: 550M # space of all repo is 10Gi: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: "[Windows] Add msbuild to PATH"
|
||||
if: matrix.os == 'Windows'
|
||||
id: add-msbuild
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
with:
|
||||
msbuild-architecture: x64
|
||||
|
||||
- name: "[macOS] Setup ccache"
|
||||
if: matrix.os == 'macOS' && matrix.use_ccache == 1
|
||||
run: brew install ccache
|
||||
|
||||
- name: "[macOS] Restore compiler cache (ccache)"
|
||||
if: matrix.os == 'macOS' && matrix.use_ccache == 1
|
||||
id: ccache_restore
|
||||
uses: actions/cache/restore@v6
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
|
||||
with:
|
||||
key: ccache-${{ matrix.runner }}-${{ matrix.soc }}-${{ matrix.type }}-${{ env.BRANCH_NAME }}
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
restore-keys: ccache-${{ matrix.runner }}-${{ matrix.soc }}-${{ matrix.type }}-
|
||||
|
||||
- name: "Install aqtinstall"
|
||||
run: pipx install aqtinstall
|
||||
|
||||
# Resolve given wildcard versions (e.g. Qt 6.6.*) to latest version via aqtinstall to avoid stale caches on new releases
|
||||
- name: "Resolve latest Qt patch version"
|
||||
env:
|
||||
QT_VERSION: ${{ matrix.qt_version }}
|
||||
id: resolve_qt_version
|
||||
shell: bash
|
||||
run: .ci/resolve_latest_aqt_qt_version.sh "$QT_VERSION"
|
||||
|
||||
- name: "[macOS] Restore thin Qt ${{ steps.resolve_qt_version.outputs.version }} libraries"
|
||||
if: matrix.os == 'macOS'
|
||||
id: restore_qt
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
key: thin-qt-macos-${{ matrix.soc }}-${{ steps.resolve_qt_version.outputs.version }}
|
||||
path: ${{ github.workspace }}/Qt
|
||||
|
||||
# Using jurplel/install-qt-action to install Qt without using brew
|
||||
# Qt build using vcpkg either just fails or takes too long to build
|
||||
- name: "[macOS] Install fat Qt ${{ steps.resolve_qt_version.outputs.version }}"
|
||||
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
cache: false
|
||||
dir: ${{ github.workspace }}
|
||||
modules: ${{ matrix.qt_modules }}
|
||||
version: ${{ steps.resolve_qt_version.outputs.version }}
|
||||
|
||||
- name: "[macOS] Create thin Qt libraries"
|
||||
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
|
||||
run: .ci/thin_macos_qtlib.sh
|
||||
|
||||
- name: "[macOS] Cache thin Qt libraries"
|
||||
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
key: thin-qt-macos-${{ matrix.soc }}-${{ steps.resolve_qt_version.outputs.version }}
|
||||
path: ${{ github.workspace }}/Qt
|
||||
|
||||
- name: "[Windows] Install Qt ${{ matrix.qt_version }}"
|
||||
if: matrix.os == 'Windows'
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
# Qt 6.11.0 only works with aqtinstall directly from git until aqtinstall 3.4 is released
|
||||
aqtsource: git+https://github.com/miurahr/aqtinstall.git
|
||||
cache: true
|
||||
modules: ${{ matrix.qt_modules }}
|
||||
version: ${{ steps.resolve_qt_version.outputs.version }}
|
||||
|
||||
- name: "[Windows] Install NSIS"
|
||||
if: matrix.os == 'Windows'
|
||||
shell: bash
|
||||
run: choco install nsis
|
||||
|
||||
- name: "Setup vcpkg cache"
|
||||
id: vcpkg-cache
|
||||
uses: TAServers/vcpkg-cache@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Uses environment variables, see compile.sh for more details
|
||||
- name: "Build Cockatrice"
|
||||
id: build
|
||||
shell: bash
|
||||
env:
|
||||
BUILDTYPE: '${{ matrix.type }}'
|
||||
CCACHE_EVICTION_AGE: ${{ matrix.ccache_eviction_age }}
|
||||
CMAKE_GENERATOR: ${{ matrix.cmake_generator }}
|
||||
CMAKE_GENERATOR_PLATFORM: ${{ matrix.cmake_generator_platform }}
|
||||
DEVELOPER_DIR: '/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer'
|
||||
MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
|
||||
MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
|
||||
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
|
||||
MAKE_PACKAGE: '${{ matrix.make_package }}'
|
||||
PACKAGE_SUFFIX: '${{ matrix.package_suffix }}'
|
||||
TARGET_MACOS_VERSION: ${{ matrix.override_target }}
|
||||
USE_CCACHE: ${{ matrix.use_ccache }}
|
||||
VCPKG_BINARY_SOURCES: 'clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite'
|
||||
VCPKG_DISABLE_METRICS: 1
|
||||
run: .ci/compile.sh --server --test --vcpkg
|
||||
|
||||
# Delete used cache to emulate a ccache update. See https://github.com/actions/cache/issues/342
|
||||
- name: "[macOS] Delete remote compiler cache (ccache)"
|
||||
if: matrix.os == 'macOS' && matrix.use_ccache == 1 && github.ref == 'refs/heads/master' && steps.ccache_restore.outputs.cache-hit
|
||||
continue-on-error: true
|
||||
env:
|
||||
CACHE_PRIMARY_KEY: ${{ steps.ccache_restore.outputs.cache-primary-key }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
if gh cache delete --repo "$GITHUB_REPOSITORY" "$CACHE_PRIMARY_KEY"; then
|
||||
echo "Cache deleted successfully"
|
||||
fi
|
||||
|
||||
- name: "[macOS] Save updated compiler cache (ccache)"
|
||||
if: matrix.os == 'macOS' && matrix.use_ccache == 1 && github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
key: ${{ steps.ccache_restore.outputs.cache-primary-key }}
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
|
||||
- name: "[macOS] Sign app bundle"
|
||||
if: matrix.os == 'macOS' && matrix.make_package && needs.configure.outputs.tag != null
|
||||
id: sign_macos
|
||||
env:
|
||||
BUILD_PATH: ${{ steps.build.outputs.path }}
|
||||
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
|
||||
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
|
||||
run: |
|
||||
if [[ -n "$MACOS_CERTIFICATE_NAME" ]]
|
||||
then
|
||||
security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
|
||||
/usr/bin/codesign --sign="$MACOS_CERTIFICATE_NAME" --entitlements=".ci/macos.entitlements" --options=runtime --force --deep --timestamp --verbose "$BUILD_PATH"
|
||||
fi
|
||||
|
||||
- name: "[macOS] Notarize app bundle"
|
||||
if: matrix.os == 'macOS' && steps.sign_macos.outcome == 'success'
|
||||
env:
|
||||
BUILD_PATH: ${{ steps.build.outputs.path }}
|
||||
MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
|
||||
MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
|
||||
MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
|
||||
run: |
|
||||
if [[ -n "$MACOS_NOTARIZATION_APPLE_ID" ]]
|
||||
then
|
||||
# Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI
|
||||
echo "Create keychain profile"
|
||||
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$MACOS_NOTARIZATION_APPLE_ID" --team-id "$MACOS_NOTARIZATION_TEAM_ID" --password "$MACOS_NOTARIZATION_PWD"
|
||||
|
||||
# We can't notarize an app bundle directly, but we need to compress it as an archive.
|
||||
# Therefore, we create a zip file containing our app bundle, so that we can send it to the
|
||||
# notarization service
|
||||
echo "Creating temp notarization archive"
|
||||
ditto -c -k --keepParent "$BUILD_PATH" "notarization.zip"
|
||||
|
||||
# Here we send the notarization request to the Apple's Notarization service, waiting for the result.
|
||||
# This typically takes a few seconds inside a CI environment, but it might take more depending on the App
|
||||
# characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
|
||||
# you're curious
|
||||
echo "Notarize app"
|
||||
xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait
|
||||
|
||||
# Finally, we need to "attach the staple" to our executable, which will allow our app to be
|
||||
# validated by macOS even when an internet connection is not available.
|
||||
echo "Attach staple"
|
||||
xcrun stapler staple "$BUILD_PATH"
|
||||
fi
|
||||
|
||||
- name: "Upload artifact"
|
||||
if: matrix.make_package
|
||||
id: upload_artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
archive: false
|
||||
if-no-files-found: error
|
||||
path: ${{ steps.build.outputs.path }}
|
||||
|
||||
- name: "[Windows] Upload PDBs (Program Databases)"
|
||||
if: matrix.os == 'Windows' && github.ref_type != 'tag'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: ${{ steps.build.outputs.name }}-PDBs
|
||||
path: |
|
||||
build/cockatrice/Release/*.pdb
|
||||
build/oracle/Release/*.pdb
|
||||
build/servatrice/Release/*.pdb
|
||||
|
||||
- name: "Upload to release"
|
||||
if: needs.configure.outputs.tag != null && matrix.make_package == '1'
|
||||
id: upload_release
|
||||
shell: bash
|
||||
env:
|
||||
asset_name: ${{ steps.build.outputs.fullname }}
|
||||
asset_path: ${{ steps.build.outputs.path }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
tag_name: ${{ needs.configure.outputs.tag }}
|
||||
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||
|
||||
- name: "Attest binary provenance"
|
||||
if: steps.upload_release.outcome == 'success'
|
||||
id: attestation
|
||||
uses: actions/attest@v4
|
||||
with:
|
||||
show-summary: false
|
||||
subject-path: ${{ steps.build.outputs.path }}
|
||||
|
||||
- name: "Verify binary attestation"
|
||||
if: steps.attestation.outcome == 'success'
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_PATH: ${{ steps.build.outputs.path }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: gh attestation verify "$BUILD_PATH" --repo Cockatrice/Cockatrice
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
name: Code Style (C++)
|
||||
|
||||
on:
|
||||
# Push trigger not needed for linting, we do not allow direct pushes to master
|
||||
pull_request:
|
||||
paths:
|
||||
- '*/**' # matches all files not in root
|
||||
- '!**.md'
|
||||
- '!.ci/**'
|
||||
- '!.github/**'
|
||||
- '!.tx/**'
|
||||
- '!doc/**'
|
||||
- '.ci/lint_cpp.sh'
|
||||
- '.github/workflows/desktop-lint.yml'
|
||||
- '.clang-format'
|
||||
- '.cmake-format.json'
|
||||
- 'format.sh'
|
||||
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-slim
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 20 # should be enough to find merge base
|
||||
|
||||
- name: "Install dependencies"
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
clang-format \
|
||||
cmake-format \
|
||||
shellcheck
|
||||
|
||||
- name: "Check code formatting"
|
||||
shell: bash
|
||||
run: ./.ci/lint_cpp.sh
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
name: Build Docker Image
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '.github/workflows/docker-release.yml'
|
||||
- 'Dockerfile'
|
||||
release:
|
||||
types:
|
||||
- released # publishing of stable releases
|
||||
|
||||
# Cancel earlier, unfinished runs of this workflow on the same branch (unless on release)
|
||||
concurrency:
|
||||
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
|
||||
cancel-in-progress: ${{ github.event_name != 'release' }}
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
name: amd64 & arm64
|
||||
if: ${{ github.repository_owner == 'Cockatrice' }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: "Docker metadata"
|
||||
id: metadata
|
||||
uses: docker/metadata-action@v6
|
||||
env:
|
||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: index # needed for GHCR
|
||||
with:
|
||||
annotations: |
|
||||
org.opencontainers.image.title=Servatrice
|
||||
org.opencontainers.image.url=https://cockatrice.github.io/
|
||||
org.opencontainers.image.description=Server for Cockatrice, a cross-platform virtual tabletop for multiplayer card games
|
||||
images: |
|
||||
ghcr.io/cockatrice/servatrice
|
||||
labels: |
|
||||
org.opencontainers.image.title=Servatrice
|
||||
org.opencontainers.image.url=https://cockatrice.github.io/
|
||||
org.opencontainers.image.description=Server for Cockatrice, a cross-platform virtual tabletop for multiplayer card games
|
||||
|
||||
- name: "Set up QEMU"
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: "Set up Docker buildx"
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: "Login to GitHub Container Registry (GHCR)"
|
||||
if: github.event_name == 'release' && github.event.release.prerelease == false
|
||||
id: login
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
password: ${{ github.token }}
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
|
||||
- name: "Build and push Docker image"
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
annotations: ${{ steps.metadata.outputs.annotations }}
|
||||
cache-from: type=gha,scope=servatrice
|
||||
cache-to: type=gha,mode=max,scope=servatrice
|
||||
context: .
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ steps.login.outcome == 'success' }}
|
||||
tags: ${{ steps.metadata.outputs.tags }}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
name: Generate Docs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'doc/doxygen/**'
|
||||
- '.github/workflows/documentation-build.yml'
|
||||
- 'Doxyfile'
|
||||
release:
|
||||
types:
|
||||
- published # publishing of stable releases and pre-releases
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
COCKATRICE_REF: ${{ github.ref_name }} # tag name if the commit is tagged, otherwise branch name
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
name: Doxygen
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: "Install Graphviz"
|
||||
run: |
|
||||
sudo apt-get install -y graphviz
|
||||
dot -V
|
||||
|
||||
- name: "Install Doxygen"
|
||||
uses: ssciwr/doxygen-install@v2
|
||||
with:
|
||||
version: "1.16.1"
|
||||
|
||||
- name: "Update Doxygen Configuration"
|
||||
run: |
|
||||
git diff Doxyfile
|
||||
doxygen -u Doxyfile
|
||||
if git diff --quiet Doxyfile; then
|
||||
echo "::notice::No config changes in Doxyfile detected."
|
||||
else
|
||||
echo "::error::Config changes in Doxyfile detected! Please update the file by running 'doxygen -u Doxyfile'."
|
||||
echo ""
|
||||
git diff --color=always Doxyfile
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: "Generate Documentation"
|
||||
if: always()
|
||||
run: doxygen Doxyfile
|
||||
|
||||
- name: "Deploy to cockatrice.github.io"
|
||||
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
with:
|
||||
deploy_key: ${{ secrets.DOCS_DEPLOY_KEY }}
|
||||
destination_dir: docs # docs will be available at https://cockatrice.github.io/docs/
|
||||
external_repository: Cockatrice/cockatrice.github.io
|
||||
publish_branch: master
|
||||
publish_dir: ./docs/html
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
name: Update Translations
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.tx/**'
|
||||
- '.github/workflows/translations-pull.yml'
|
||||
schedule:
|
||||
# Runs in the middle of each month starting a quarter (UTC) = two weeks after new strings are built
|
||||
- cron: '0 0 15 1,4,7,10 *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
translations:
|
||||
# Do not run the scheduled workflow on forks
|
||||
if: github.event_name != 'schedule' || github.repository_owner == 'Cockatrice'
|
||||
|
||||
name: Pull languages
|
||||
runs-on: ubuntu-slim
|
||||
|
||||
steps:
|
||||
- name: "Checkout repo"
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: "Pull translated strings from Transifex"
|
||||
# Do not run this step for PR's from forks, they don't have access to the secret
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false
|
||||
uses: transifex/cli-action@v2
|
||||
with:
|
||||
# Used config file: https://github.com/Cockatrice/Cockatrice/blob/master/.tx/config
|
||||
# Docs: https://github.com/transifex/cli#pulling-files-from-transifex
|
||||
args: pull --force --all
|
||||
token: ${{ secrets.TX_TOKEN }}
|
||||
|
||||
- name: "Create pull request"
|
||||
if: github.event_name != 'pull_request'
|
||||
id: create_pr
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
with:
|
||||
add-paths: |
|
||||
cockatrice/translations/*.ts
|
||||
oracle/translations/*.ts
|
||||
author: github-actions <github-actions@github.com> # owner of the commit
|
||||
body: |
|
||||
Pulled all translated strings from [Transifex][1].
|
||||
|
||||
---
|
||||
*This PR is automatically generated and updated by the workflow at `.github/workflows/translations-pull.yml`. Review [action runs][2].*<br>
|
||||
*After merging, all new languages and translations are available in the next build.*
|
||||
|
||||
[1]: https://explore.transifex.com/cockatrice/cockatrice/
|
||||
[2]: https://github.com/Cockatrice/Cockatrice/actions/workflows/translations-pull.yml?query=branch%3Amaster
|
||||
branch: ci-update_translations
|
||||
commit-message: Update translation files
|
||||
delete-branch: true
|
||||
draft: false
|
||||
labels: |
|
||||
CI
|
||||
Translation
|
||||
title: 'Update translations'
|
||||
|
||||
- name: "PR Status"
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
env:
|
||||
PR_NUMBER: ${{ steps.create_pr.outputs.pull-request-number }}
|
||||
PR_URL: ${{ steps.create_pr.outputs.pull-request-url }}
|
||||
STATUS: ${{ case(steps.create_pr.outputs.pull-request-operation == 'none', 'unchanged', steps.create_pr.outputs.pull-request-operation) }}
|
||||
run: |
|
||||
echo "PR #$PR_NUMBER $STATUS!" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "URL: $PR_URL" >> "$GITHUB_STEP_SUMMARY"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
name: Update Translation Source
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.ci/update_translation_source_strings.sh'
|
||||
- '.github/workflows/translations-push.yml'
|
||||
schedule:
|
||||
# Runs at the start of each quarter (UTC)
|
||||
- cron: '0 0 1 1,4,7,10 *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
translations:
|
||||
# Do not run the scheduled workflow on forks
|
||||
if: github.event_name != 'schedule' || github.repository_owner == 'Cockatrice'
|
||||
|
||||
name: Push strings
|
||||
runs-on: ubuntu-slim
|
||||
|
||||
steps:
|
||||
- name: "Checkout repo"
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: "Install lupdate"
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends qttools5-dev-tools
|
||||
|
||||
- name: "Update Cockatrice translation source"
|
||||
env:
|
||||
FILE: cockatrice/cockatrice_en@source.ts
|
||||
id: cockatrice
|
||||
shell: bash
|
||||
run: >
|
||||
DIRS="cockatrice/src $(find . -maxdepth 1 -type d -name 'libcockatrice_*')"
|
||||
.ci/update_translation_source_strings.sh
|
||||
|
||||
- name: "Update Oracle translation source"
|
||||
id: oracle
|
||||
shell: bash
|
||||
env:
|
||||
DIRS: 'oracle/src'
|
||||
FILE: 'oracle/oracle_en@source.ts'
|
||||
run: .ci/update_translation_source_strings.sh
|
||||
|
||||
- name: "Render template"
|
||||
id: template
|
||||
uses: chuhlomin/render-template/binary@v1
|
||||
with:
|
||||
template: .ci/update_translation_source_strings_template.md
|
||||
vars: |
|
||||
cockatrice_output: ${{ steps.cockatrice.outputs.output }}
|
||||
oracle_output: ${{ steps.oracle.outputs.output }}
|
||||
commit: ${{ github.sha }}
|
||||
|
||||
- name: "Create pull request"
|
||||
if: github.event_name != 'pull_request'
|
||||
id: create_pr
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
with:
|
||||
add-paths: |
|
||||
cockatrice/cockatrice_en@source.ts
|
||||
oracle/oracle_en@source.ts
|
||||
author: github-actions <github-actions@github.com> # owner of the commit
|
||||
body: ${{ steps.template.outputs.result }}
|
||||
branch: ci-update_translation_source
|
||||
commit-message: Update translation source strings
|
||||
delete-branch: true
|
||||
draft: false
|
||||
labels: |
|
||||
CI
|
||||
Translation
|
||||
title: 'Update source strings'
|
||||
|
||||
- name: "PR Status"
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
env:
|
||||
PR_NUMBER: ${{ steps.create_pr.outputs.pull-request-number }}
|
||||
PR_URL: ${{ steps.create_pr.outputs.pull-request-url }}
|
||||
STATUS: ${{ case(steps.create_pr.outputs.pull-request-operation == 'none', 'unchanged', steps.create_pr.outputs.pull-request-operation) }}
|
||||
run: |
|
||||
echo "PR #$PR_NUMBER $STATUS!" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "URL: $PR_URL" >> "$GITHUB_STEP_SUMMARY"
|
||||
Reference in New Issue
Block a user