Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Publish Release Action #650

Merged
merged 7 commits into from
Jan 15, 2021
Merged

Add Publish Release Action #650

merged 7 commits into from
Jan 15, 2021

Conversation

altrisi
Copy link
Collaborator

@altrisi altrisi commented Dec 29, 2020

After over 50 iterations, it's here!

I present you, the Release Action! (or Stopping Github Bot from taking over the repo, both are correct).

Fixes people complaining about Curseforge being outdated.
Fixes merge docs making a mess of commits that have to be pulled all the time.
Fixes people not finding rules or functions because they haven't been released yet.

This action, the largest by far, incorporates everything (*check below) needed for a release:

  • Building multiple branches (after many iterations, new branches can be "easily" added, since now you just need a new matrix entry instead of copying the job with different variables).
  • Uploading those built jars to the Github release
  • Uploading those built jars to the Curseforge page
  • Merging Scarpet docs only when the release is going live
  • Updating the Rules wiki page only when the release is going live

Everything controlled via the always modified anyway gradle.properties file. This PR adds 3 new fields to it:

  • release-curse-versions: The Curseforge versions for the main branch, since CF versioning is cursed.
  • release-extra-branch (boolean): Whether or not an extra branch should be built (e.g. a snapshots release)
    If disabled, only the released (master) branch will be processed, and all the options below won't do anything.
  • release-extra-branch-name: The name of the extra branch to build and publish
  • release-extra-curse-version: The Curseforge version for the extra branch, since CF doesn't use snapshot names but something a lot more generic (1.16-Snapshots or even 1.17 right now).
    In master branch it will be assumed to be the same as minecraft_version

How does a release created with this look like?

Well, I can't show a Curseforge example since I can't do those releases, but I can show you the Github release and the final action run. [updated]

Github Release: https://github.com/altrisi/fabric-carpet/releases/tag/test53
Action run: https://github.com/altrisi/fabric-carpet/actions/runs/484398817

That action run includes a debug step where the Curseforge parameters passed are shown instead of uploading there. That is removed in this final action.

Example HTMLShopped Curseforge entry (note: second is incorrect, Minecraft isn't currently in the sentence):

imagen

imagen

How to call this action?

Well, here comes the catch: Adding this means that every version needs to have it's own release (and therefore tag). There's nothing you can really do about this without being extremely prone to errors (a way I thought about keeping the old releases "model" was to make this run on release edited, but then you couldn't reliably upload assets since it could be fixing a typo not adding release, etc).

Anyway, this is simple to call: Publish a new release with it's own tag (in master branch) and a description. That's all. Of course add a title so it looks good on Github, but it wouldn't really be needed.

It will then start doing everything, parallelizing tasks when possible to make it faster. Builds from both branches (if both are enabled) will start, and they will be uploaded to Github as soon as they are built. If one of them fails, the other one will be instantly cancelled (I can change that if you want).

Same with docs and wiki, they will start running at the same time, those without caring if one fails, and when done they will be directly committed to it's respective place. This will be the only merge docs commits you'll see after adding this.

The description will be used as CF changelog, and if you mark it as a pre-release, it will be marked as beta in CF too.

What if a hotfix is needed?

You have to upload it manually to the release. There will be no problem with that, but of course Curseforge won't be updated.

Is there something needed to make this work other than merging?

Yes. CurseForge doesn't allow anyone to upload releases for any project, so you need to add a Curseforge API token to this.
Luckily, Github provides a place to store tokens secretly preventing them from ever getting published, and this action is already configured to use a token in that storage.

Therefore, you need to add your Curseforge token (which you can get here) into your secret's store as CF_API_TOKEN in Settings > Secrets > New repository secret.

Once that's done, everything should work directly.

Is this fully tested?

Well, yes, but actually no. Everything except the Curseforge release is fully tested, in both the single-release scenario and the multi-release one.

The Curseforge release, however, couldn't be tested, basically because I can't publish to Carpet's Curseforge page and I don't have any mods in there to test with. Although I haven't directly tested it, I checked all variables passed there and they all seem to be correct, since I printed them in tests as if the release was running, and they all matched.

Therefore, in the first release with this I'll need to check that the CF step worked correctly, but it should.

What things other than releases are added/removed/lost with this?

  • Merge docs and rules to wiki will no longer show that ugly (x) Process completed with exit code 1 in the action run when there is nothing to update. It will instead be logged without problems
  • Both merge-docs and rules-to-wiki individual actions are removed since they are now included in this action.
  • The wiki will sadly no longer say [pusher] edited this page ... but github-actions[bot]..., since the release event doesn't contain last pusher information in a way that works for the commit name.

What other things could be done in this that aren't? I saw that asterisk!

Well, the only thing that isn't done in this action that also happens on every release (that I could think of) is uploading artifacts to maven.

It is something that can be done, but I don't have the required information to do it.

Publishing to maven is something that is usually added in the build.gradle publishing section, that could be added perfectly fine here in case masa's maven can be used with Gradle's system (which I suppose it can). In order to keep secret things like username, password and maybe also the url, you don't need to add them in the file, but use them from environment variables (replace with ENV.username, etc in gradle.properties), and then passing them through Secrets to the action.

If added, the maven publishing step in the action could be executed at the end, after publishing to Github and CF, mostly to prevent the Github release being empty for too long in case the connection is slow (it currently is for less than 2min).

I can try to integrate this if given the base in build.gradle.

Another thing would maybe be sending a Discord notification. It could actually be done relatively easily, but not only not every Carpet release is currently published to Discord, also I didn't find it being necessary.

Complements to this action

Merged!

While not fully needed, there is one thing that can be done to make this even better, in both automation and having a proper title in CF. It is something that is enabled by default in the Fabric's example mod (and it's still technically enabled in Carpet, just overridden), that was removed in c7c0da9 (yes, the forth commit to Carpet), that automatically fills the version field of the fabric.mod.json with the current version in gradle.properties when building.

You can see it still existing in Carpet here:

processResources {
inputs.property "version", project.version
from(sourceSets.main.resources.srcDirs) {
include "fabric.mod.json"
expand "version": project.version
}
from(sourceSets.main.resources.srcDirs) {
exclude "fabric.mod.json"
}
}

In order to re-automate that, only three things would need to be done:

  • Replace the version field of fabric.mod.json with ${version}
  • Change the mod version in gradle.properties to not include the date so it doesn't break semver
  • Add the date in gradle build aside from the mod_version using something like formatting the new Date() function into the suffix (would also automate setting the date)

This affects the CF title because the mod_version field (with date) is used to generate the release title.

Tell me if you want this too.

Edit: This would also need the variable in Gradle to be changed to project.mod_version, since at some point version was changed to include Minecraft version too.

file_path: build/libs/${{ steps.findjar.outputs.jarname }}
changelog_type: markdown
changelog: ${{ github.event.release.body }}
display_name: Carpet Mod v${{ needs.Get-Properties.outputs.carpet-version }} for ${{ steps.getbranchinfo.outputs.version }}
Copy link
Collaborator Author

@altrisi altrisi Dec 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since 1.17 snapshots, this may be too vague (cf version for all 1.17 snapshots is 1.17 and will probably stay the same for release).

Should I add an entry for an extra word/words after the CF version? Or maybe just add Snapshots if on that branch?

An example name with this current phrase would be:
Carpet Mod v1.4.123 for 1.17
Which may need an extra "Snapshots" word (this was thought with 1.16 in mind, when the CF version was 1.16-Snapshots)

@gnembon
Copy link
Owner

gnembon commented Jan 1, 2021

So when creating a new release with a new tag I just need to provide the changelog, and files will be added automatically, right?

@altrisi
Copy link
Collaborator Author

altrisi commented Jan 2, 2021

Yes, basically:

  • Update version (s) in gradle.properties and CarpetSettings.java and push
  • Click create a new release
  • Mark it to make a tag, master branch (or whatever other is the main branch if you change it, though then merge-docs needs updating)
  • Add a changelog
  • Hit publish

And that will start merging docs, updating wiki, building jars and publishing those to Github and CF.

Before that remember that you have to add the CF_API_TOKEN to Github Secrets once.

This, however, wouldn't publish to maven because that's not configured in the script. I've just added a step in the action to upload at least the maven folder to the action artifacts (so it doesn't need to be built locally, that wouldn't make sense), but this would ideally be added to the buildscript with something like:

publishing {
    [...]
    repositories {
        [...]
        def ENV = System.getenv()
        if (ENV.MAVEN_URL) {
            maven {
                url ENV.MAVEN_URL
                credentials {
                    username ENV.MAVEN_USERNAME
                    password ENV.MAVEN_PASSWORD
                }
            }
        }
    }
}

and then passing those variables through Github Secrets in the action, so they are accessible only for publishing, something like:

[...]
- name: Publish to maven
  run: ./gradlew publish
  env:
    MAVEN_URL: ${{ secrets.MAVEN_URL }}
    MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
    MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}

That's the only missing bit of automation if I'm not missing something else.

So they don't have to be built locally again
@gnembon
Copy link
Owner

gnembon commented Jan 7, 2021

technical question about maven. its technically on masa's https://masa.dy.fi/maven
but I do access it via scp right now uploading into carpet/fabric-carpet
You think just the URL and scp creds would work here? how maven is able to serve carpet content based on main url of the maven itself?

@altrisi
Copy link
Collaborator Author

altrisi commented Jan 7, 2021

Not sure, since I've never really published to a maven (at least yet), but as far as I've read, Gradle supports Maven repos with the default Maven publishing plugin (already applied to Carpet's buildscript), and Maven supports scp.

At least in the current local publishing "repo" (folder), the result seems to follow the same structure as in the Maven, so that part shouldn't fail.

You could test it next release by locally adding it to see if it works, and if it does, make it available in the repo for Action usage. I suppose it will simply fail if credentials aren't compatible, shouldn't harm.

@gnembon
Copy link
Owner

gnembon commented Jan 13, 2021

will merge that tomorrow - want to avoid potential issues on potential snapshot day.

@altrisi
Copy link
Collaborator Author

altrisi commented Jan 14, 2021

Wait, this may need an extra field for curseforge version of the main branch, since I didn't remember it can also target snapshots, which may not be available in Curse's cursed versioning.

@gnembon
Copy link
Owner

gnembon commented Jan 14, 2021

if you could figure that out that would complete the setup.

@gnembon
Copy link
Owner

gnembon commented Jan 14, 2021

My guess is currently it would work only for 1.16.4 version, right?

@altrisi
Copy link
Collaborator Author

altrisi commented Jan 14, 2021

Yeah, that's also right. The problem I saw here, however, was that since it's based on mod_version, and that is usually the latest supported in the branch, so the latest names are available, if it was 1.16.5-rc1 or something like that CF would probably reject it.

It's also a good way to specify multiple versions in their list, that's true.

@altrisi
Copy link
Collaborator Author

altrisi commented Jan 14, 2021

Ok, so that is now done, and the CF versions are specified in their own field, release-curse-versions.

Updated previews:

Full summary of things this action does:
On new release created:

  • Merge docs and wiki
  • Build up to 2 branches ("easily" expandable, configurable) in parallel
  • Upload those built releases to the Github release
  • Upload those built releases to CF with configurable versions
  • Ask Gradle to publish (runs gradlew publish, currently only to folder)
  • Upload that folder to the Action run so it doesn't need to be built locally, since that doesn't make sense.
    This is intended to be removed when that is properly automated.

What this doesn't (currently) do:

  • Merging docs in a branch not called master. It is currently hardcoded for simplicity. (it will actually merge docs for whatever is in the master branch and commit to master when creating a release from any other branch)
  • Upload to maven
    Can be added by either adding the repo to Gradle publish, or if incompatible, add an action step with all required bash commands to publish it. Else just get the artifacts from the action run and locally upload them

What is needed for this:

  • Add the CF_API_TOKEN secret

Things that may be considered:

@gnembon gnembon merged commit 2c7dd1c into gnembon:master Jan 15, 2021
@altrisi altrisi deleted the release-action branch June 11, 2021 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants