gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

CONTRIBUTING.md (26554B)


      1 # Contribution Guidelines <!-- omit in toc -->
      2 
      3 Hey! Welcome to the CONTRIBUTING.md for GoToSocial :) Thanks for taking a look, that kicks ass.
      4 
      5 These contribution guidelines were adapted from / inspired by those of Gitea (https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md). Thanks Gitea!
      6 
      7 ## Table of Contents  <!-- omit in toc -->
      8 
      9 - [Introduction](#introduction)
     10 - [Bug reports and feature requests](#bug-reports-and-feature-requests)
     11 - [Pull requests](#pull-requests)
     12   - [Code](#code)
     13   - [Documentation](#documentation)
     14 - [Development](#development)
     15   - [Golang forking quirks](#golang-forking-quirks)
     16   - [Building GoToSocial](#building-gotosocial)
     17     - [Binary](#binary)
     18     - [Docker](#docker)
     19       - [With GoReleaser](#with-goreleaser)
     20       - [Manually](#manually)
     21   - [Stylesheet / Web dev](#stylesheet--web-dev)
     22     - [Live Reloading](#live-reloading)
     23   - [Project Structure](#project-structure)
     24     - [Finding your way around the code](#finding-your-way-around-the-code)
     25   - [Style / Linting / Formatting](#style--linting--formatting)
     26   - [Testing](#testing)
     27     - [Standalone Testrig with Semaphore](#standalone-testrig-with-semaphore)
     28     - [Running automated tests](#running-automated-tests)
     29       - [SQLite](#sqlite)
     30       - [Postgres](#postgres)
     31     - [CLI Tests](#cli-tests)
     32     - [Federation](#federation)
     33   - [Updating Swagger docs](#updating-swagger-docs)
     34   - [CI/CD configuration](#cicd-configuration)
     35   - [Release Checklist](#release-checklist)
     36     - [What if something goes wrong?](#what-if-something-goes-wrong)
     37 
     38 ## Introduction
     39 
     40 This document contains important information that will help you to write a successful contribution to GoToSocial. Please read it carefully before opening a pull request!
     41 
     42 ## Bug reports and feature requests
     43 
     44 Currently, we use Github's issue system for tracking bug reports and feature requests.
     45 
     46 You can view all open issues [here](https://github.com/superseriousbusiness/gotosocial/issues "The Github Issues page for GoToSocial").
     47 
     48 Before opening a new issue, whether bug or feature request, **please search carefully through both open and closed issues to make sure it hasn't been addressed already**. You can use Github's keyword issue search for this. If your issue is a duplicate of an existing issue, it will be closed.
     49 
     50 Before you open a feature request issue, please consider the following:
     51 
     52 - Does this feature fit within the scope of GoToSocial? Since we are a small team, we are wary of [feature creep](https://en.wikipedia.org/wiki/Feature_creep "Wikipedia article on Feature Creep"), which can cause maintenance issues.
     53 - Will this feature be generally useful for many users of the software, or is it handy for only a very specific use case?
     54 - Will this feature have a negative impact on the performance of the software? If so, is the tradeoff worth it?
     55 - Does this feature require loosening API security restrictions in some way? If so, it will need a good justification.
     56 - Does this feature belong in GoToSocial's server backend, or is it something that a client could implement instead?
     57 
     58 We tend to prioritize feature requests related to accessibility, fedi interoperability, and client compatibility.
     59 
     60 ## Pull requests
     61 
     62 We welcome pull requests from new and existing contributors, with the following provisos:
     63 
     64 - You have read and agree to our Code of Conduct.
     65 - The pull request addresses an existing issue or bug (please link to the relevant issue in your pull request), or is related to documentation.
     66 - If your pull request introduces significant new code paths, you are willing to do some maintenance work on those code paths, and address bugs. We do not appreciate drive-by pull requests that introduce a significant maintenance burden!
     67 - The pull request is of decent quality. We are a small team and unfortunately we don't have a lot of time to help shepherd pull requests, or help with basic coding questions. If you're unsure, don't bite off more than you can chew: start with a small feature or bugfix for your first PR, and work your way up.
     68 
     69 If you have small questions or comments before/during the pull request process, you can [join our Matrix space](https://matrix.to/#/#gotosocial-space:superseriousbusiness.org "GoToSocial Matrix space") at `#gotosocial-space:superseriousbusiness.org`.
     70 
     71 Please read the appropriate section below for the kind of pull request you plan to open.
     72 
     73 ### Code
     74 
     75 To keep things manageable for maintainers, the process for opening pull requests against the GoToSocial repository works roughly as follows:
     76 
     77 1. Open an issue for the feature, bug, or issue your pull request will address, or comment on an existing issue to let everyone know you want to work on it.
     78 2. Use the open issue to discuss your design with us, gather feedback, and resolve any concerns about the implementation.
     79 3. Write your code! Make sure all existing tests pass. Add tests where appropriate. Run linters and formatters. Update documentation.
     80 4. Open your pull request. You can do this as a draft, if you want to gather more feedback on code-in-progress.
     81 5. Let us know that your pull request is ready to be reviewed.
     82 6. Wait for review.
     83 7. Address review comments, make changes to the code where appropriate. It's OK to push back on review comments if you have a sensible reason--we're all learning, after all--but please do so with patience and grace.
     84 8. Get your code merged, rejoice!
     85 
     86 To make your code easier to review, try to split your pull request into sensibly-sized commits, but don't worry too much about making it totally perfect: we always squash merge anyways.
     87 
     88 If your pull request ends up being massive, consider splitting it into smaller discrete pull requests to make it easier to review and reason about.
     89 
     90 Make sure your pull request only contains code that's relevant to the feature you're trying to implement, or the bug you're trying to address. Don't include refactors of unrelated parts of the code in your pull request: make a separate PR for that!
     91 
     92 If you open a code pull request without following the above process, we may close it and ask you to follow the process instead.
     93 
     94 ### Documentation
     95 
     96 The process for documentation pull requests is a bit looser than the process for code.
     97 
     98 If you see something in the documentation that's missing, wrong, or unclear, feel free to open a pull request addressing it; you don't necessarily need to open an issue first, but please explain why you're opening the PR in the PR comment.
     99 
    100 We support a [Conda](https://docs.conda.io/en/latest/)-based workflow for hacking, building & publishing the documentation. Here's how you can get started locally:
    101 
    102 * Install [`miniconda`](https://docs.conda.io/en/latest/miniconda.html)
    103 * Create your conda environment: `conda env create -f ./docs/environment.yml`
    104 * Activate the environment: `conda activate gotosocial-docs`
    105 * Serve locally: `mkdocs serve`
    106 
    107 Then you can visit [localhost:8000](http://127.0.0.1:8000/) in your browser to view.
    108 
    109 If you don't use Conda, you can read the `docs/environment.yml` to see which dependencies are required and `pip install` them manually.
    110 
    111 ## Development
    112 
    113 ### Golang forking quirks
    114 
    115 One of the quirks of Golang is that it relies on the source management path being the same as the one used within `go.mod` and in package imports within individual Go files. This makes working with forks a bit awkward.
    116 
    117 Let's say you fork GoToSocial to `github.com/yourgithubname/gotosocial`, and then clone that repository to `~/go/src/github.com/yourgithubname/gotosocial`. You will probably run into errors trying to run tests or build, so you might change your `go.mod` file so that the module is called `github.com/yourgithubname/gotosocial` instead of `github.com/superseriousbusiness/gotosocial`. But then this breaks all the imports within the project. Nightmare! So now you have to go through the source files and painstakingly replace `github.com/superseriousbusiness/gotosocial` with `github.com/yourgithubname/gotosocial`. This works OK, but when you decide to make a pull request against the original repo, all the changed paths are included! Argh!
    118 
    119 The correct solution to this is to fork, then clone the upstream repository, then set `origin` of the upstream repository to that of your fork.
    120 
    121 See [this blog post](https://blog.sgmansfield.com/2016/06/working-with-forks-in-go/) for more details.
    122 
    123 In case this post disappears, here are the steps (slightly modified):
    124 
    125 >
    126 > Fork the repository on GitHub or set up whatever other remote git repo you will be using. In this case, I would go to GitHub and fork the repository.
    127 >
    128 > Now clone the upstream repo (not the fork):
    129 >
    130 > `mkdir -p ~/go/src/github.com/superseriousbusiness && git clone git@github.com:superseriousbusiness/gotosocial ~/go/src/github.com/superseriousbusiness/gotosocial`
    131 >
    132 > Navigate to the top level of the upstream repository on your computer:
    133 >
    134 > `cd ~/go/src/github.com/superseriousbusiness/gotosocial`
    135 >
    136 > Rename the current origin remote to upstream:
    137 >
    138 > `git remote rename origin upstream`
    139 >
    140 > Add your fork as origin:
    141 >
    142 > `git remote add origin git@github.com/yourgithubname/gotosocial`
    143 >
    144 
    145 ### Building GoToSocial
    146 
    147 #### Binary
    148 
    149 To get started, you first need to have Go installed. GtS is currently using Go 1.20, so you should take that too. See [here](https://golang.org/doc/install) for installation instructions.
    150 
    151 Once you've got go installed, clone this repository into your Go path. Normally, this should be `~/go/src/github.com/superseriousbusiness/gotosocial`.
    152 
    153 Once you've installed the prerequisites, you can try building the project: `./scripts/build.sh`. This will build the `gotosocial` binary.
    154 
    155 If there are no errors, great, you're good to go!
    156 
    157 For automatic re-compiling during development, you can use [nodemon](https://www.npmjs.com/package/nodemon):
    158 
    159 ```bash
    160 nodemon -e go --signal SIGTERM --exec "go run ./cmd/gotosocial --host localhost testrig start || exit 1"
    161 ```
    162 
    163 #### Docker
    164 
    165 For both of the below methods, you need to have [Docker buildx](https://docs.docker.com/buildx/working-with-buildx/) installed.
    166 
    167 ##### With GoReleaser
    168 
    169 GoToSocial uses the release tooling [GoReleaser](https://goreleaser.com/intro/) to make multiple-architecture + Docker builds simple.
    170 
    171 GoReleaser is also used by GoToSocial for building and pushing Docker containers.
    172 
    173 Normally, these processes are handled by Drone (see CI/CD above). However, you can also invoke GoReleaser manually for things like building snapshots.
    174 
    175 To do this, first [install GoReleaser](https://goreleaser.com/install/).
    176 
    177 Then install GoSwagger as described in [the Swagger section](#updating-swagger-docs).
    178 
    179 Then install Node and Yarn as described in [Stylesheet / Web dev](#stylesheet--web-dev).
    180 
    181 Finally, to create a snapshot build, do:
    182 
    183 ```bash
    184 goreleaser --rm-dist --snapshot
    185 ```
    186 
    187 If all goes according to plan, you should now have a number of multiple-architecture binaries and tars inside the `./dist` folder, and snapshot Docker images should be built (check your terminal output for version).
    188 
    189 ##### Manually
    190 
    191 If you prefer a simple approach to building a Docker container, with fewer dependencies (go-swagger, Node, Yarn), you can also just build in the following way:
    192 
    193 ```bash
    194 ./scripts/build.sh && docker buildx build -t superseriousbusiness/gotosocial:latest .
    195 ```
    196 
    197 The above command first builds the `gotosocial` binary, then invokes Docker buildx to build the container image.
    198 
    199 If you want to build a docker image for a different CPU architecture without setting up buildx (for example for ARMv7 aka 32-bit ARM), first modify the Dockerfile by adding the following lines to the top (but don't commit this!):
    200 
    201 ```dockerfile
    202 # When using buildx, these variables will be set by the tool:
    203 # https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
    204 # However, declaring them as global build arguments like this allows them to be set manually with `--build-arg` instead. 
    205 ARG BUILDPLATFORM
    206 ARG TARGETPLATFORM
    207 ```
    208 
    209 Then, you can use the following command:
    210 
    211 ```bash
    212 GOOS=linux GOARCH=arm ./scripts/build.sh && docker build --build-arg BUILDPLATFORM=linux/amd64 --build-arg TARGETPLATFORM=linux/arm/v7 -t superseriousbusiness/gotosocial:latest .
    213 ```
    214 
    215 See also: [exhaustive list of GOOS and GOARCH values](https://gist.github.com/lizkes/975ab2d1b5f9d5fdee5d3fa665bcfde6)
    216 
    217 And: [exhaustive list of possible values for docker's `--platform`](https://github.com/tonistiigi/binfmt/#build-test-image)
    218 
    219 ### Stylesheet / Web dev
    220 
    221 GoToSocial uses Gin templates in the `web/template` folder. Static assets are stored in `web/assets`. Source files for stylesheets and JS bundles (for frontend enhancement, and the settings interface) are stored in `web/source`, and bundled from there to the `web/assets/dist` folder (gitignored).
    222 
    223 To bundle changes, you need [Node.js](https://nodejs.org/en/download/) and [Yarn](https://classic.yarnpkg.com/en/docs/install).
    224 
    225 Using [NVM](https://github.com/nvm-sh/nvm) is one convenient way to install them which also supports managing different Node versions.
    226 
    227 To install Yarn dependencies:
    228 
    229 ```bash
    230 yarn install --cwd web/source
    231 ```
    232 
    233 To recompile bundles:
    234 
    235 ```bash
    236 node web/source
    237 ```
    238 
    239 #### Live Reloading
    240 
    241 For a more convenient development environment, you can run a livereloading version of the bundler alongside the [testrig](#testing).
    242 
    243 Open two terminals, first start the testrig on port 8081:
    244 ``` bash
    245 GTS_PORT=8081 go run ./cmd/gotosocial testrig start
    246 ```
    247 Then start the bundler, which will run on port 8080, and proxy requests to the testrig instance where needed.
    248 ``` bash
    249 NODE_ENV=development node web/source
    250 ```
    251 
    252 The livereloading bundler *will not* change the bundled assets in `dist/`, so once you are finished with changes and want to deploy it somewhere, you have to run `node web/source` to generate production-ready bundles.
    253 
    254 ### Project Structure
    255 
    256 For project structure, GoToSocial follows a standard and widely accepted project layout [defined here](https://github.com/golang-standards/project-layout). As the author writes:
    257 
    258 > This is a basic layout for Go application projects. It's not an official standard defined by the core Go dev team; however, it is a set of common historical and emerging project layout patterns in the Go ecosystem.
    259 
    260 Where possible, we prefer more files and packages of shorter length that very clearly pertain to definable chunks of application logic, rather than fewer but longer files: if one `.go` file is pushing 1,000 lines of code, it's probably too long.
    261 
    262 #### Finding your way around the code
    263 
    264 Most of the crucial business logic of the application is found inside the various packages and subpackages of the `internal` directory. Here's a brief summary of each of these:
    265 
    266 `internal/ap` - ActivityPub utility functions and interfaces.
    267 
    268 `internal/api` - Models, routers, and utilities for the client and federated (ActivityPub) APIs. This is where routes are attached to the router, and where you want to be if you're adding a route.
    269 
    270 `internal/concurrency` - Worker models used by the processor and other queues.
    271 
    272 `internal/config` - Code for configuration flags, CLI flag parsing, and getting/setting config.
    273 
    274 `internal/db` - DB interfaces for interacting with sqlite/postgres databases. Database migration code is in `internal/db/bundb/migrations`.
    275 
    276 `internal/email` - Email functionality, email sending via SMTP.
    277 
    278 `internal/federation` - ActivityPub federation code; implements `go-fed` interfaces.
    279 
    280 `internal/federation/federatingdb` - Implementation of `go-fed`'s Database interface.
    281 
    282 `internal/federation/dereferencing` - Code for making http calls to fetch resources from remote instances.
    283 
    284 `internal/gotosocial` - GoToSocial server startup/shutdown logic.
    285 
    286 `internal/gtserror` - Error models.
    287 
    288 `internal/gtsmodel` - Database and internal models. This is where `bundb` annotations live.
    289 
    290 `internal/httpclient` - The HTTP client used by GoToSocial for making requests to remote resources.
    291 
    292 `internal/id` - Code for generating IDs (ULIDs) for database models.
    293 
    294 `internal/log` - Our logging implementation.
    295 
    296 `internal/media` - Code related to managing + processing media attachments; images, video, emojis, etc.
    297 
    298 `internal/messages` - Models for wrapping worker messages.
    299 
    300 `internal/middleware` - Gin Gonic router middlewares: http signature checking, cache control, token checks, etc.
    301 
    302 `internal/netutil` - HTTP / net request validation code.
    303 
    304 `internal/oauth` - Wrapper code/interfaces for OAuth server implementation.
    305 
    306 `internal/oidc` - Wrapper code/interfaces for OIDC claims and callbacks.
    307 
    308 `internal/processing` - Logic for processing messages produced by the federation or client APIs. Much of the core business logic of GoToSocial is contained here.
    309 
    310 `internal/regexes` - Regular expressions used for text parsing and matching of URLs, hashtags, mentions, etc.
    311 
    312 `internal/router` - Wrapper for Gin HTTP router. Core HTTP logic is contained here. The router exposes functions for attaching routes, which are used by the code in `internal/api` handlers.
    313 
    314 `internal/storage` - Wrapper for `codeberg.org/gruf/go-store` implementations. Local file storage and s3 logic goes here.
    315 
    316 `internal/stream` - Websockets streaming logic.
    317 
    318 `internal/text` - Text parsing and transformation. Status parsing logic is contained here -- both plain and markdown.
    319 
    320 `internal/timeline` - Status timeline management code.
    321 
    322 `internal/trans` - Code for exporting models to json backup files from the database, and importing backup json files into the database.
    323 
    324 `internal/transport` - HTTP transport code and utilities.
    325 
    326 `internal/typeutils` - Code for converting from internal database models to json, and back, or from ActivityPub format to internal database model format and vice versa. Basically, serdes.
    327 
    328 `internal/uris` - Utilities for generating URIs used throughout GoToSocial.
    329 
    330 `internal/util` - Odds and ends; small utility functions used by more than one package.
    331 
    332 `internal/validate` - Model validation code -- currently not really used.
    333 
    334 `internal/visibility` - Status visibility checking and filtering.
    335 
    336 `internal/web` - Web UI handlers, specifically for serving web pages, the landing page, settings panels.
    337 
    338 ### Style / Linting / Formatting
    339 
    340 It is a good idea to read the short official [Effective Go](https://golang.org/doc/effective_go) page before submitting code: this document is the foundation of many a style guide, for good reason, and GoToSocial more or less follows its advice.
    341 
    342 Another useful style guide that we try to follow: [this one](https://github.com/bahlo/go-styleguide).
    343 
    344 In addition, here are some specific highlights from Uber's Go style guide which agree with what we try to do in GtS:
    345 
    346 - [Group Similar Declarations](https://github.com/uber-go/guide/blob/master/style.md#group-similar-declarations).
    347 - [Reduce Nesting](https://github.com/uber-go/guide/blob/master/style.md#reduce-nesting).
    348 - [Unnecessary Else](https://github.com/uber-go/guide/blob/master/style.md#unnecessary-else).
    349 - [Local Variable Declarations](https://github.com/uber-go/guide/blob/master/style.md#local-variable-declarations).
    350 - [Reduce Scope of Variables](https://github.com/uber-go/guide/blob/master/style.md#reduce-scope-of-variables).
    351 - [Initializing Structs](https://github.com/uber-go/guide/blob/master/style.md#initializing-structs).
    352 
    353 Before you submit any code, make sure to run `go fmt ./...` to update whitespace and other opinionated formatting.
    354 
    355 We use [golangci-lint](https://golangci-lint.run/) for linting, which allows us to catch style inconsistencies and potential bugs or security issues, using static code analysis.
    356 
    357 If you make a PR that doesn't pass the linter, it will be rejected. As such, it's good practice to run the linter locally before pushing or opening a PR.
    358 
    359 To do this, first install the linter following the instructions [here](https://golangci-lint.run/usage/install/#local-installation).
    360 
    361 Then, you can run the linter with:
    362 
    363 ```bash
    364 golangci-lint run
    365 ```
    366 
    367 If there's no output, great! It passed :)
    368 
    369 ### Testing
    370 
    371 GoToSocial provides a [testrig](https://github.com/superseriousbusiness/gotosocial/tree/main/testrig) with a number of mock packages you can use in integration tests.
    372 
    373 One thing that *isn't* mocked is the Database interface because it's just easier to use an in-memory SQLite database than to mock everything out.
    374 
    375 #### Standalone Testrig with Semaphore
    376 
    377 You can launch a testrig as a standalone server running at localhost, which you can connect to using something like [Semaphore](https://github.com/NickColley/semaphore/).
    378 
    379 To do this, first build the gotosocial binary with `DEBUG=1 ./scripts/build.sh`.
    380 
    381 Then, launch the testrig with the `DEBUG` environment variable set by invoking the binary as follows:
    382 
    383 ```bash
    384 DEBUG=1 ./gotosocial testrig start
    385 ```
    386 
    387 To run Semaphore locally in dev mode, first clone the [Semaphore](https://github.com/NickColley/semaphore/) repository, and then run the following commands in the cloned directory:
    388 
    389 ```bash
    390 yarn # install dependencies
    391 yarn run dev
    392 ```
    393 
    394 The Semaphore instance will start running on `localhost:4002`.
    395 
    396 To connect to the testrig, navigate to `http://localhost:4002` and enter your instance name as `localhost:8080`.
    397 
    398 At the login screen, enter the email address `zork@example.org` and password `password`. You will get a confirmation prompt. Accept, and you are logged in as Zork.
    399 
    400 Note the following constraints:
    401 
    402 - Since the testrig uses an in-memory database, the database will be destroyed when the testrig is stopped.
    403 - If you stop the testrig and start it again, any tokens or applications you created during your tests will also be removed. As such, you need to log out and in again every time you stop/start the rig.
    404 - The testrig does not make any actual external HTTP calls, so federation will not work from a testrig.
    405 
    406 #### Running automated tests
    407 
    408 Tests can be run against both SQLite and Postgres.
    409 
    410 ##### SQLite
    411 
    412 If you would like to run tests as quickly as possible, using an SQLite in-memory database, use:
    413 
    414 ```bash
    415 go test ./...
    416 ```
    417 
    418 ##### Postgres
    419 
    420 If you want to run tests against a Postgres database on localhost, run:
    421 
    422 ```bash
    423 GTS_DB_TYPE="postgres" GTS_DB_ADDRESS="localhost" go test -p 1 ./...
    424 ```
    425 
    426 In the above command, it is assumed you are using the default Postgres password of `postgres`.
    427 
    428 We set `-p 1` when running against Postgres because it requires tests to run in serial, not in parallel.
    429 
    430 #### CLI Tests
    431 
    432 In [./test/envparsing.sh](./test/envparsing.sh) there's a test for making sure that CLI flags, config, and environment variables get parsed as expected.
    433 
    434 Although this test *is* part of the CI/CD testing process, you probably won't need to worry too much about running it yourself. That is, unless you're messing about with code inside the `main` package in `cmd/gotosocial`, or inside the `config` package in `internal/config`.
    435 
    436 #### Federation
    437 
    438 By using the support for loading TLS files from disk it is possible to have two local instances with TLS to allow for (manually) testing federation.
    439 
    440 You'll need to set the following configuration options:
    441 * `GTS_TLS_CERTIFICATE_CHAIN`: poiting to a PEM-encoded certificate chain including the public certificate
    442 * `GTS_TLS_CERTIFICATE_KEY`: pointing to a PEM-encoded private key
    443 
    444 Additionally, for the Go HTTP client to recognise certificates issued by a custom CA as valid, you'll need to set one of:
    445 * `SSL_CERT_FILE`: pointing to the public key of your custom CA
    446 * `SSL_CERT_DIR`: a `:`-separated list of directories to load CA certificates from
    447 
    448 You'll additionally need functioning DNS for your two instance names which you can achieve through entries in `/etc/hosts` or by running a local DNS server like [dnsmasq](https://thekelleys.org.uk/dnsmasq/doc.html).
    449 
    450 ### Updating Swagger docs
    451 
    452 GoToSocial uses [go-swagger](https://goswagger.io) to generate Swagger API documentation from code annotations.
    453 
    454 You can install go-swagger following the instructions [here](https://goswagger.io/install.html).
    455 
    456 If you change Swagger annotations on any of the API paths, you can generate a new Swagger file at `./docs/api/swagger.yaml` by running:
    457 
    458 ```bash
    459 swagger generate spec --scan-models --exclude-deps -o docs/api/swagger.yaml
    460 ```
    461 
    462 ### CI/CD configuration
    463 
    464 GoToSocial uses [Drone](https://www.drone.io/) for CI/CD tasks like running tests, linting, and building Docker containers.
    465 
    466 These runs are integrated with GitHub, and will be run on opening a pull request or merging into main.
    467 
    468 The Drone instance for GoToSocial is [here](https://drone.superseriousbusiness.org/superseriousbusiness/gotosocial).
    469 
    470 The `drone.yml` file is [here](./.drone.yml) — this defines how and when Drone should run. Documentation for Drone is [here](https://docs.drone.io/).
    471 
    472 It is worth noting that the `drone.yml` file must be signed by the Drone admin account to be considered valid. This must be done every time the file is changed. This is to prevent tampering and hijacking of the Drone instance. See [here](https://docs.drone.io/signature/).
    473 
    474 To sign the file, first install and setup the [drone cli tool](https://docs.drone.io/cli/install/). Then, run:
    475 
    476 ```bash
    477 drone -t PUT_YOUR_DRONE_ADMIN_TOKEN_HERE -s https://drone.superseriousbusiness.org sign superseriousbusiness/gotosocial --save
    478 ```
    479 
    480 ### Release Checklist
    481 
    482 First things first: If this is a security hot-fix, we'll probably rush through this list, and make a prettier release a few days later.
    483 
    484 Now, with that out of the way, here's our Checklist.
    485 
    486 GoToSocial follows [Semantic Versioning](https://semver.org/).
    487 So our first concern on the Checklist is:
    488 
    489 - What version are we releasing?
    490 
    491 Next we need to check:
    492 
    493 - Do the assets have to be rebuilt and committed to the repository.
    494 - Do the swagger docs have to be rebuilt?
    495 
    496 On the project management side:
    497 
    498 - Are there any issues that have to be moved to a different milestone?
    499 - Are there any things on the [Roadmap](./ROADMAP.md) that can be ticked off?
    500 
    501 Once we're happy with our Checklist, we can create the tag, and push it.
    502 And the rest [is automation](./.drone.yml).
    503 
    504 We can now head to GitHub, and add some personality to the release notes.
    505 Finally, we make announcements on the all our channels that the release is out!
    506 
    507 #### What if something goes wrong?
    508 
    509 Sometimes things go awry.
    510 We release a buggy release, we forgot something ­ something important.
    511 
    512 If the release is so bad that it's unusable ­ or dangerous! ­ to a great part of our user-base, we can pull.
    513 That is: Delete the tag.
    514 
    515 Either way, once we've resolved the issue, we just start from the top of this list again. Version numbers are cheap. It's cheap to burn them.