forked from cadey/xesite
203 lines
6.6 KiB
Markdown
203 lines
6.6 KiB
Markdown
|
---
|
||
|
title: "gitea-release Tool Announcement"
|
||
|
date: "2020-05-31"
|
||
|
tags:
|
||
|
- gitea
|
||
|
- rust
|
||
|
- release
|
||
|
---
|
||
|
|
||
|
# gitea-release Tool Announcement
|
||
|
|
||
|
I'm a big fan of automating things that can possibly be automated. One of the
|
||
|
biggest pains that I've consistently had is creating/tagging releases of
|
||
|
software. This has been a very manual process for me. I have to write up
|
||
|
changelogs, bump versions and then replicate the changelog/versions in the web
|
||
|
UI of whatever git forge the project in question is using. This works great at
|
||
|
smaller scales, but can quickly become a huge pain in the butt when this needs
|
||
|
to be done more often. Today I've written a small tool to help me automate this
|
||
|
going forward, it is named
|
||
|
[`gitea-release`](https://tulpa.dev/cadey/gitea-release). This is one of my
|
||
|
largest Rust projects to date and something I am incredibly happy with. I will
|
||
|
be using it going forward for all of my repos on my gitea instance
|
||
|
[tulpa.dev](https://tulpa.dev).
|
||
|
|
||
|
`gitea-release` is a spiritual clone of the tool [`github-release`][ghrelease],
|
||
|
but optimized for my workflow. The biggest changes are that it works on
|
||
|
[gitea][gitea] repos instead of github repos, is written in Rust instead of Go
|
||
|
and it automatically scrapes release notes from `CHANGELOG.md` as well as
|
||
|
reading the version of the software from `VERSION`.
|
||
|
|
||
|
[ghrelease]: https://github.com/github-release/github-release
|
||
|
[gitea]: https://gitea.io
|
||
|
|
||
|
## CHANGELOG.md and VERSION files
|
||
|
|
||
|
The `CHANGELOG.md` file is based on the [Keep a Changelog][kacl] format, but
|
||
|
modified slightly to make it easier for this tool. Here is an example changelog
|
||
|
that this tool accepts:
|
||
|
|
||
|
[kacl]: https://keepachangelog.com/en/1.0.0/
|
||
|
|
||
|
```markdown
|
||
|
# Changelog
|
||
|
All notable changes to this project will be documented in this file.
|
||
|
|
||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||
|
|
||
|
## 0.1.0
|
||
|
|
||
|
### FIXED
|
||
|
|
||
|
- Refrobnicate the spurious rilkefs
|
||
|
|
||
|
## 0.0.1
|
||
|
|
||
|
First release, proof of concept.
|
||
|
```
|
||
|
|
||
|
When a release is created for version 0.1.0, this tool will make the description
|
||
|
of the release about as follows:
|
||
|
|
||
|
```
|
||
|
### FIXED
|
||
|
|
||
|
- Refrobnicate the spurious rilkefs
|
||
|
```
|
||
|
|
||
|
This allows the changelog file to be the ultimate source of truth for release
|
||
|
notes with this tool.
|
||
|
|
||
|
The `VERSION` file plays into this as well. The `VERSION` file MUST be a single
|
||
|
line containing a [semantic version][semver] string. This allows the `VERSION`
|
||
|
file to be the ultimate source of truth for software version data with this
|
||
|
tool.
|
||
|
|
||
|
[semver]: https://semver.org/spec/v2.0.0.html
|
||
|
|
||
|
## Release Process
|
||
|
|
||
|
When this tool is run with the `release` subcommand, the following actions take place:
|
||
|
|
||
|
- The `VERSION` file is read and loaded as the desired tag for the repo
|
||
|
- The `CHANGELOG.md` file is read and the changes for the `VERSION` are
|
||
|
cherry-picked out of the file
|
||
|
- The git repo is checked to see if that tag already exists
|
||
|
- If the tag exists, the tool exits and does nothing
|
||
|
- If the tag does not exist, it is created (with the changelog fragment as the
|
||
|
body of the tag) and pushed to the gitea server using the supplied gitea token
|
||
|
- A gitea release is created using the changelog fragment and the release name
|
||
|
is generated from the `VERSION` string
|
||
|
|
||
|
## Automation of the Automation
|
||
|
|
||
|
This tool works perfectly well locally, but this doesn't make it fully
|
||
|
automated from the gitea repo. I use [drone][drone] as a CI/CD tool for my gitea
|
||
|
repos. Drone has a very convenient and simple to use [plugin
|
||
|
system][droneplugin] that was easy to integrate with [structopt][structopt].
|
||
|
|
||
|
[drone]: https://drone.io
|
||
|
[droneplugin]: https://docs.drone.io/plugins/overview/
|
||
|
[structopt]: https://crates.io/crates/structopt
|
||
|
|
||
|
I created a drone plugin at `xena/gitea-release` that can be configured as a
|
||
|
pipeline step in your `.drone.yml` like this:
|
||
|
|
||
|
```yaml
|
||
|
kind: pipeline
|
||
|
name: ci/release
|
||
|
steps:
|
||
|
- name: whatever unit testing step
|
||
|
# ...
|
||
|
- name: auto-release
|
||
|
image: xena/gitea-release:0.2.5
|
||
|
settings:
|
||
|
auth_username: cadey
|
||
|
changelog_path: ./CHANGELOG.md
|
||
|
gitea_server: https://tulpa.dev
|
||
|
gitea_token:
|
||
|
from_secret: GITEA_TOKEN
|
||
|
when:
|
||
|
event:
|
||
|
- push
|
||
|
branch:
|
||
|
- master
|
||
|
```
|
||
|
|
||
|
This allows me to bump the `VERSION` and `CHANGELOG.md`, then push that commit
|
||
|
to git and a new release will automatically be created. You can see an example
|
||
|
of this in action with [the drone build history of the gitea-release
|
||
|
repo](https://drone.tulpa.dev/cadey/gitea-release). You can also how the
|
||
|
`CHANGELOG.md` file grows with the [CHANGELOG of
|
||
|
gitea-release](https://tulpa.dev/cadey/gitea-release/src/branch/master/CHANGELOG.md).
|
||
|
|
||
|
Once the release is pushed to gitea, you can then use drone to trigger
|
||
|
deployment commands. For example here is the deployment pipeline used to
|
||
|
automatically update the docker image for the gitea-release tool:
|
||
|
|
||
|
```yaml
|
||
|
kind: pipeline
|
||
|
name: docker
|
||
|
steps:
|
||
|
- name: build docker image
|
||
|
image: "monacoremo/nix:2020-04-05-05f09348-circleci"
|
||
|
environment:
|
||
|
USER: root
|
||
|
commands:
|
||
|
- cachix use xe
|
||
|
- nix-build docker.nix
|
||
|
- cp $(readlink result) /result/docker.tgz
|
||
|
volumes:
|
||
|
- name: image
|
||
|
path: /result
|
||
|
when:
|
||
|
event:
|
||
|
- tag
|
||
|
|
||
|
- name: push docker image
|
||
|
image: docker:dind
|
||
|
volumes:
|
||
|
- name: image
|
||
|
path: /result
|
||
|
- name: dockersock
|
||
|
path: /var/run/docker.sock
|
||
|
commands:
|
||
|
- docker load -i /result/docker.tgz
|
||
|
- echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
|
||
|
- docker push xena/gitea-release
|
||
|
environment:
|
||
|
DOCKER_USERNAME:
|
||
|
from_secret: DOCKER_USERNAME
|
||
|
DOCKER_PASSWORD:
|
||
|
from_secret: DOCKER_PASSWORD
|
||
|
when:
|
||
|
event:
|
||
|
- tag
|
||
|
|
||
|
volumes:
|
||
|
- name: image
|
||
|
temp: {}
|
||
|
- name: dockersock
|
||
|
host:
|
||
|
path: /var/run/docker.sock
|
||
|
```
|
||
|
|
||
|
This pipeline will use [Nix](https://nixos.org/nix) to build the docker image,
|
||
|
load it into a Docker daemon and then log into the Docker Hub and push it. This
|
||
|
can then be used to do whatever you want. It may also be a good idea to push a
|
||
|
docker image for every commit and then re-label the tagged commits, but this
|
||
|
wasn't implemented in this repo.
|
||
|
|
||
|
---
|
||
|
|
||
|
I hope this tool will be useful. I will accept feedback over [any contact
|
||
|
method](/contact). If you want to contribute directly to the project, please
|
||
|
feel free to create [issues](https://tulpa.dev/cadey/gitea-release/issues) or
|
||
|
[pull requests](https://tulpa.dev/cadey/gitea-release/pulls). If you don't want
|
||
|
to create an account on my git server, get me the issue details or code diffs
|
||
|
somehow and I will do everything I can to fix issues and integrate code. I just
|
||
|
want to make this tool better however I can.
|
||
|
|
||
|
Be well.
|