pat-s 7e05552752
All checks were successful
continuous-integration/drone/push Build is passing
add files
2023-02-06 17:08:25 +01:00

2.8 KiB

Website PR Previews with Gitea and Drone CI

This is a guide on how to setup a Gitea repository with Drone CI to automatically build and deploy a website preview in a pull requests via AWS S3.


  • Drone CI
  • Permission (access key pair) to create AWS S3 buckets
  • Admin access to Gitea repo


The CI build executes the following steps:

  1. Build website
  2. Create a new S3 bucket with a static website endpoint using the repo name and PR index
  3. Push/sync the website output to the S3 bucket
  4. Add a comment to the PR with the S3 bucket URL

An optional, but currently not possible, step would be to delete the S3 bucket after the PR is closed. Unfortunately Drone CI does currently not allow to trigger runs on PR close events for Gitea. See this issue for more information. Nevertheless, the code for deleting the S3 bucket is already included in the drone.yml file (but commented out).

Secrets in PRs

When using this approach, one must allow to use certain secrets (AWS access key and Gitea access token) in PRs. This can be dangerous as anyone could open a PR which triggers a run and expose the secrets in the log.

Therefore, the tokens used should have minimal scopes. On the AWS side, they should only be allowed to operate on regex-controlled S3 buckets matching the "preview" pattern for the repo.


Since Gitea 1.19, one can create tokens with a limited scope. A token with the repo scope is sufficient for this use case. Also note that the issuing user of the token will be displayed as the user posting the comment. You might want to create a programmatic "bot" user for this purpose.


For AWS, you should create an access key pair for a user which only has access to the S3 buckets used for the previews. This can be done by creating a policy which only allows access to the buckets matching the "preview" pattern for the respective repo (adapt to your needs!).

  "Version": "2012-10-17",
  "Statement": [
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": [
      "Resource": ["arn:aws:s3:::preview-*", "arn:aws:s3:::preview-*/"]

By default, the bucket is public. If you want to avoid that, you can add additional restrictions to the bucket policy. A common one is to restrict by IP range.