Alrighty, time to add some Drone CI to the mix to get those automatic releases happening. First things first, let’s start Drone CI and get it connected to Gitea. Drone CI provide reasonable documentation, so I won’t go into all the details but basically:

  1. Create an OAuth app in Gitea.
    • Make note of the Client Secret when shown to you, as it’s the only time it’ll be shown.
    • Make sure you provide the appropriate Redirect URI. In our case, this should be http://drone:8080/login.
  2. Create a secret, however you want really. We’ll use this for the `
  3. Add the below to our existing docker-compose file.
    • Be sure to provide the appropriate Client ID, Client Secret and DRONE_RPC_SECRET. Make something up for that last one, it can be whatever you want. Ideally something strong. 😄
  drone:
    image: drone/drone:2
    container_name: drone
    environment:
      - DRONE_SERVER_HOST=drone:8080
      - DRONE_SERVER_PROTO=http
      - DRONE_GITEA_CLIENT_ID=<your-client-id-here>
      - DRONE_GITEA_CLIENT_SECRET=<your-client-secret-here>
      - DRONE_GITEA_SERVER=http://gitea:3000
      - DRONE_RPC_SECRET=<your-rpc-secret-here>
      - DRONE_USER_CREATE=username:gitea,admin:true
    volumes:
      - drone:/data
    ports:
      - 8080:80
    restart: unless-stopped

  runner:
    image: drone/drone-runner-docker:1
    container_name: runner
    environment:
      - DRONE_RPC_PROTO=http
      - DRONE_RPC_HOST=drone
      - DRONE_RPC_SECRET=<your-rpc-secret-here>
      - DRONE_RUNNER_CAPACITY=2
      - DRONE_RUNNER_NAME=jovial-easley
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - drone
    restart: unless-stopped

Let’s start Drone CI now.

$ docker-compose up -d
Recreating gitea ... done
Creating drone   ... done
Creating runner  ... done

Hit http://drone:8080 and you should see Hello, Welcome to Drone.. Awesome! Click continue and you should be redirected to Gitea with a prompt to authorize drone to access your account. Accept and you should be redirected back to Drone to Complete your Drone Registration.. I actually just leave these blank and hit submit, it’s fine.

Sweet, now I can see gitea/crimp-city listed under repositories. Click on it and then on Activate Repository. When you do this, Drone CI creates a webhook in Gitea, telling it to send it an update when a commit is made. You can ignore everything else for now.

So Gitea knows it should tell Drone CI when this repo gets a new commit. Let’s test this out. Create a .drone.yml file in the root of the crimp-city repo.

# .drone.yml

kind: pipeline
name: default

steps:
  - name: run
    image: golang
    commands:
      - go run main.go

Add, commit and push this change up to Gitea.

$ git add .drone.yml
$ git commit -m "Add drone ci config"
[master 693d656] Add drone ci config
 1 file changed, 10 insertions(+)
 create mode 100644 .drone.yml
$ git push
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 12 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 686 bytes | 686.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0), pack-reused 0
remote: . Processing 1 references
remote: Processed 1 references in total
To http://gitea:3000/gitea/crimp-city.git
   4836926..693d656  master -> master

I checked the build tab in Drone and… nothing. Huh, that’s odd. I venture over to the crimp-city repo in Gitea, open the settings and webhooks tab, scrolling down to the bottom and, ah. A failed delivery.

Delivery: Post "http://drone:8080/hook?secret=kzpOpiciNP5TJDv2x3nKh4lb3MzNiI3n": dial tcp 172.23.0.3:8080: connect: connection refused

Oh. Yes. More network fun. Gitea is using the internal docker-compose network, where Drone is actually listening on port 80 and not 8080. We can fix this easily by scrolling back up the page and updated the Target URL to http://drone/hook?secret=kzpOpiciNP5TJDv2x3nKh4lb3MzNiI3n.

To test this is now working, we can add a README to crimp-city.

# crimp-city

Testing that Gitea can talk to Drone CI!

Do the git add/commit/push dance and then check that Drone CI builds tab again. Sweet! Success. I can click through and view output from the two stages of the build, the clone and the run step.

Time to make it actually do releases though. Update the Drone CI config file.

# .drone.yml

kind: pipeline
name: default

steps:
  - name: fetch
    image: docker:git
    commands:
      - git fetch --tags

  # we don't have tests, awkward
  # - name: test
  #   image: golang:1.17
  #   volumes:
  #     - name: deps
  #       path: /go
  #   commands:
  #     - go test -race -v ./... -cover

  - name: release
    image: golang:1.17
    environment:
      GITEA_TOKEN:
        from_secret: gitea_token
    volumes:
      - name: deps
        path: /go
    commands:
      - curl -sL https://git.io/goreleaser | bash
    when:
      event:
        - tag

volumes:
  - name: deps
    temp: {}

Why do we have the fetch step? Per the GoRelease Drone CI documentation:

By default, drone does not fetch tags. plugins/git is used with default values, in most cases we’ll need overwrite the clone step enabling tags in order to make goreleaser work correctly.

One thing we’ll need to do is set a secret in Drone CI, so that GoReleaser can talk to Gitea. You may remember this as our GITEA_TOKEN. You can use the same one as before or create a new dedicated secret. If it was production, I’d do the latter.

To set the secret, go into Drone CI, click through to the crimp-city repo, Settings -> Secrets -> + New Secret. Name it gitea_token and the value to the secret, then create.

Git add/commit/push the updated Drone CI config. Time to check what happened in the latest build logs from the runner. We have our clone and fetch steps but no release? This is because set to only run that step when the commit has a tag. Let’s try that out now.

$ git tag -a v0.1.1 -m "Testing Drone CI and GoReleaser"
$ git push origin v0.1.1
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 180 bytes | 180.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
remote: . Processing 1 references
remote: Processed 1 references in total
To http://gitea:3000/gitea/crimp-city.git
 * [new tag]         v0.1.1 -> v0.1.1

Check out the builds again annnnnnnnd…

Woman celebrating

It ran through the release stage as well! And if we check Gitea, we can see that there are now two releases. Awesome!


Here we conclude. I actually finished writing a thing. Word. I’m considering creating video tutorials and putting them up on YouTube because man, is it effort writing all this out. That’s probably my bad for not tactically using screenshots though, so, I apologise. Get in touch on Twitter or elsewhere if you have any questions or difficulties.

Peace out and I’ll see you in my next post.