Introduces a new workflow that runs when a new build has been published
on GitHub Releases. It converts the release notes to Hangar Markdown and
sends it to Hangar along with the jar-file.
Note: The workflow currently relies on the version string being appended
to the filename of the jar-file. Without it, the file reference in the
`curl` request that uploads the build would need to change.
The workflow references a new secret, `HANGAR_TOKEN`, which is just an
API key for the Hangar API. The token was created in the Hangar profile
settings (API Keys), and its only permission is `create_version`.
In order to properly upload a new build to Hangar, we need to construct
a somewhat complex JSON object. This is because the Hangar API allows
for publishing releases on multiple platforms and for multiple versions,
which makes the simple use case for MobArena's single file upload look a
bit overcomplicated. Unlike the CurseForge API, the Hangar API supports
"normal" platform version strings, so we don't need to map anything. It
also supports patch version wildcards, so we can get away with `1.18.x`,
`1.19.x`, etc. for each version supported. The API only uses the API key
for authentication, which means we need to grab a JWT and use that for
the actual upload request. Note that the `pluginDependencies` property
is currently required, but it can be left empty.
The workflow can be invoked directly via the `workflow_dispatch` event,
which might come in handy if something in the pipeline breaks.
The Hangar base URL and project slug are both hardcoded, and things
would probably be cleaner if they were made into variables, but we don't
need this workflow anywhere else, so it's fine for now.
Introduces a new workflow that runs when a new build has been published
on GitHub Releases. It converts the release notes to CurseForge HTML and
sends it to CurseForge along with the jar-file.
Note: The workflow currently relies on the version string being appended
to the filename of the jar-file. Without it, the file reference in the
`curl` request that uploads the build would need to change.
The workflow references a new secret, `CURSEFORGE_TOKEN`, which is just
an API key for the CurseForge API. The token was created on CurseForge
under profile settings (My API Tokens).
In order to properly upload a new build to CurseForge, we need a list of
"game version IDs", which isn't completely trivial. The API gives us a
means of looking up _all_ Minecraft game version IDs, but we then have
to manually filter out the ones that don't apply to Bukkit plugins, as
there are duplicate entries for each Minecraft version, and only some of
them work for Bukkit plugins (which turns out to be the ones with game
version type ID 1). The structure of the `metadata` field combined with
how incredibly difficult bash can be to work with has resulted in some
gnarly text processing trying to filter the JSON response and turning it
into a list for use in the `jq` template, but it gets the job done.
The CurseForge base URL and project ID are both hardcoded, and things
would probably be cleaner if they were made into variables, but we don't
need this workflow anywhere else, so it's fine for now.
The workflow can be invoked directly via the `workflow_dispatch` event,
which might come in handy if something in the pipeline breaks.
Lots of inspiration was found in the probably really great GitHub Action
`curseforge-upload` [1]. We could have probably just used that, but it's
nice to have full control of the process. At any rate, thanks to itsmeow
and NotMyFault for publishing their work.
---
[1] https://github.com/itsmeow/curseforge-upload
This commit adds a second job to the build workflow that runs after the
build job has completed. The job creates a GitHub Releases _draft_ that
needs to be manually published in order to be publicly available.
The job runs if, and only if, the following conditions are met:
- The build job has completed _successfully_, i.e. if the Gradle `build`
task fails, the draft job doesn't run.
- The `push` event that triggered the workflow happened on the `master`
branch, i.e. releases will never be created from temporary branches.
- The commit message of the most recent commit in the `push` event that
triggered the workflow starts with `"Release "`, i.e. there must be a
commit that explicitly tries to "release" a build.
- The version string does _not_ end with `-SNAPSHOT`, i.e. development
builds will not be released.
All of these conditions act as safeguards, so we don't end up releasing
something we don't want to release, but they also prevent bloating the
Releases page with a bunch of useless drafts.
The job uses the `version` output variable from the build job that was
introduced in a recent commit to extract release notes using the script
that was also introduced recently, as well as for the name of the _tag_
to create when the release is published.
Note that the `GITHUB_TOKEN` environment variable is required to be set
when we want to use the GitHub CLI in a workflow [1]. The job also has
an explicit `contents: write` permission, which is required for creating
releases from GitHub Actions.
This commit makes the build workflow output the version string as found
in the `version` property in `build.gradle.kts`. The version string will
be necessary further down the pipeline when we need to extract release
notes and create tags.
There are many ways to extract the version string:
- Use `grep` to grab it from `build.gradle.kts` directly. This is pretty
brittle, since we don't really know for sure if the structure of the
file will change in the future.
- Create a Gradle task in `build.gradle.kts` that prints the version
string. This is probably the most direct approach we could take, but
such a hyper-specific task feels like a code smell. It also requires
running Gradle again, which is a bit slow.
- Use the built-in `properties` task in Gradle to print the `version`
property and `grep` it. We avoid changing `build.gradle.kts`, which is
a plus, but we still have to actually run Gradle.
- Parse the filename of the resulting jar-file in `build/libs/`, since
it now contains the version string. This is also brittle, because we
don't know if we're gonna continue to append the version string to the
jar-file, and depending so much on it being there is a little scary.
- Extract `plugin.yml` from the resulting jar-file and `grep` it. This
is perhaps a little crude, but it is much faster than running Gradle,
and as a bonus, we get a bit closer to "what's inside the jar-file",
which should give us a bit more confidence that any given release is
actually the version it claims to be.
It may seem like a small thing to invest so much text on, but from an
automation standpoint, it is much easier to be confident in automations
with predictable and robust mechanisms for deriving input variables.
According to the documentation, by not specifying anything in the `push`
event, GitHub Actions will run the workflow for both branches and tags,
but by specifying `branches` alone, it will _only_ run the workflow for
branches and _not_ tags [1].
We want to build on pushes to _all_ branches so we can give folks a jar
to try out for feature requests and bug fixes. We don't want to build on
tags, however, because they don't provide any value in the current build
pipeline. If the version was derived from Git tags, it could make sense
to build on tags, but that's not where we are.
As for the `**` glob pattern instead of just `*`, the documentation says
that the latter does not match forward slashes [2], and while our naming
convention for branches doesn't use slashes right now, there's no reason
that they shouldn't be viable later down the road.
---
[1] https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushbranchestagsbranches-ignoretags-ignore
[2] https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
Removes the "archive version" override for the `shadowJar` task in the
build file, resulting in a jar-file that contains the current version
number in the filename. It's mostly a convenience tradeoff; either we
can see the version directly in the filename and avoid assumptions, or
we can easily overwrite an existing jar-file with a new one.
Also updates the upload step of the build workflow to a glob pattern so
we grab the file regardless of the version.
This commit converts the project from Maven to Gradle by removing the
old Maven-related files such as `pom.xml` and the Maven Wrapper, and
replacing them with their Gradle counterparts (more or less).
Comparing the artifacts from Maven and Gradle indicates no significant
differences in the resulting jar-files, and a quick test of the plugin
shows that things are still working as expected.
Bits of `build.gradle.kts` may need a bit of a tune-up later down the
road, e.g. the test sources "hack" put in place. It may be cleaner to
omit this hack and just suck up having to repeat dependencies, but in
that case, it might be better to embrace the "libs" file instead of
having to repeat dependencies in full.
Note that this commit changes the caching mechanism used in the GitHub
Actions build workflow, opting for the one built into `setup-java`.
The previous name was really just a way to try to "prettify" the whole
thing, but the badge in the README is a little wonky compared to other
projects, so we're just gonna go with "build" for now for consistency.
This commit introduces a Github Actions workflow in the form of the file
`.github/workflows/build.yml`, replacing Travis CI and its `.travis.yml`
file.
The new workflow does a little bit more than Travis CI: it uploads an
artifact after a successful build. Due to a known issue with Github's
package UI, the MobArena.jar file is dynamically zipped on download, so
we get MobArena.jar.zip containing just MobArena.jar. It's redundant,
but there doesn't seem to be a simple way around it at the time of this
commit, so we'll leave it be.
For now, the workflow runs on every push to every branch. I'm probably
going to regret that, but we'll leave that as it is for now as well.
The existing issue template tries to cover everything, and as a result it is a bit overwhelming. Using multiple issue templates trims the noise when you know what kind of issue you're submitting.
The goal of the contributing guidelines is to give contributors some
concrete dos and don'ts to work by, effectively making it easier on
everybody involved.