This is a short tutorial on how to create and maintain a Copr repository for your software in an automated fashion. It assumes some basic familiarity with Git & how to create a RPM package.
TIP: You can set up similar automation when packaging someone else's program, i.e. building from a downloaded source tarball. The needed modifications are described xref:#_packaging_from_source_tarballs[at the end of the tutorial].
. Our program's source in a _publicly available git repository_ somewhere. This tutorial uses a simple example program - hellocopr - to demonstrate the process. The program and all files referenced in this guide can be found in the link:https://pagure.io/copr-tito-quickdoc[project's git repository]. It's a very simple (& pointless) python program with a setuptools installer:
. A _Fedora (FAS) account_ in order to be able to create repositories on Copr. This tutorial's demo repository can be found link:https://copr.fedorainfracloud.org/coprs/lcts/hellocopr/[here].
. The utility _`tito`_ installed on your system. link:https://github.com/rpm-software-management/tito[Tito] is capable of a lot of advanced automation for package creation, most of which we won't need here. Check out its documentation to learn more.
. A _specfile_ for our program. For more information on how to create one,
TIP: You can follow along with this tutorial by cloning or forking the repository and checking out the `initial` tag. This will put the repository in the state just before the next step. The repo's commit history matches the steps followed in this tutorial.
Copy link:https://pagure.io/copr-tito-quickdoc/c/00963ac9339a13eefd2ab1ca42b1f72af12d3cac?branch=master[the spec file] into the project's base directory. A few changes should be made before proceeding:
. The values of `Version:` and `Release:` do not matter, since these will be managed by tito. It makes sense to set them to `Version: 0.0.0` and `Release: 0%\{?dist}` to mark that this package hasn't been built yet.
. tito will also handle the creation of the source tarball from the git repository, so change the _`Source0:` URL_ to the filename `%\{name}-%\{version}.tar.gz` & add a comment to tell users how to get the tarball
This creates link:https://pagure.io/copr-tito-quickdoc/c/7a6919d3dd56943bb988a755f8233157965aa9bb?branch=master[a subdirectory `.tito` with some default configuration], which can be left unchanged for now.
We can now do a test build of the package using _`tito build`_. Usually, tito will build from a tag, which we haven't created yet. However, using the `--test` flag, we can build from the most recent commit instead, which will be written to `/tmp/tito`:
Once we've fixed any issues with the package that might crop up, we can let _tito_ create a package release using `tito tag`. Since we haven't set a proper version yet, we need to pass it to tito for the first tag:
This will open the editor & display a pre-formatted changelog entry build up from all commits since the last release, which we can edit as needed. Since there have been none so far, the entry will just contain "- new package built with tito". Save the file, link:https://pagure.io/copr-tito-quickdoc/c/f44e81d695df669bcdb7237612baf41b80da98e0?branch=master[and tito will]
. Go to https://copr.fedorainfracloud.org/ and log in. Once done, click on _New Project_ to start creating a repository for our program. On the following input mask,
.. Under _1. Project information_ -> _Project name_ set the name to what you want your repo to be called - since this will only contain a single package, it makes sense to use projectname = packagename, i.e. _hellocopr_. This is the only settings that cannot be changed later.
.. Under _4. Other Options_ make sure that _Follow Fedora branching_ is ticked, this will ensure that your repository will automatically update for new Fedora release.
. Your package will appear in the list of packages. Hit _Rebuild_ to trigger a build. The following page lets you change any build options if necessary, we'll just use the defaults, i.e. the options we set in the previous step. Hit _Submit_ and Copr will build the package from the tito tag we created in Step 1.
Next, we want to set up Copr to automatically build a new package version whenever we create one, so that we no longer need to log in and trigger one manually. To achieve this, we simply need to trigger a build whenever we push a new tag to the repository.
This requires some configuration both of your Git repository and of the Copr project.
Configuration can be found under _Settings_ -> _Integrations_, the page also explains the steps to configure your git repository for all common Git forges (Pagure, Github, Gitlab & Bitbucket).
Now, to test this, let's make some changes to our program that will come in handy for the final layer of automation and create a new release for our software.
Currently, the example program has its version hardcoded at multiple places. link:https://pagure.io/copr-tito-quickdoc/c/61abf1cdf622d8c9fb4f03eb6b06c4ddc1677362?branch=master[Let's change this] so that the version string is sourced from a single file. Which file this is doesn't matter, but ideally the version variable should be the only thing in it that is likely to change. In this case, we use the previously empty `src/hellocopr/pass:[__]initpass:[__].py`. We name this new version '1.0.1'.
Push the resulting commit & tag, and if you now check your projects page on Copr, you'll see that a new build of `hellocopr-1.0.1-1` has been triggered by our pushing a tag.
If you check the git log, you'll find that I actually forgot to update hellocopr's version variable to 1.0.1. We don't want that to happen again. Luckily, since we single-source our version, we can let tito automatically generate this file from a template.
First, copy the version source file `src/hellocopr/pass:[__]initpass:[__].py` to `.tito/templates/pass:[__]initpass:[__].py.template`. Then, open the template file and replace the version string with `$version`. It also makes sense to add a note that the file is managed by tito and should not be edited manually.
https://pagure.io/copr-tito-quickdoc/c/28600f6e41d5a4b60f2e47cf077f2fe2d9224e1d?branch=master[Commit the changes]. Now, when we tag a new release, tito will take the template, replace `$version` with whatever version was tagged, and copy the resulting file to `src/hellocopr/pass:[__]initpass:[__].py` before updating the spec file and commiting the changes.
. Also in the spec file, set the `Version:` back to whatever version the program is at and `Source0:` back to the tarball URL. You can use macros like `%\{version}` for the latter to automatically follow version changes.
The rest of the procedure stays the same. If you make changes to the package without changing the source, you can just tag a new release with tito. If you do update the source tarball, you need to update the `Version:` field and reset `Release:` to `0%\{?dist}` before tagging.
TIP: The tarball-adapted version of the project can be found in the `https://pagure.io/copr-tito-quickdoc/tree/foreign-sources[foreign-sources]` branch of the git repo.