How to release an Ansible collection step by step

Hello everyone!

In the previous posts we created a dummy Ansible module and set up a repository for a collection for the module and other future content.

Now we want to contribute back to Ansible by sharing the collection.

As we want to be cool open source project developers, and maybe even submit our automation masterpiece for inclusion in the Ansible community package in future, we’ll follow the approach developed by maintainers of the community collections living under the ansible-collections GitHub org like community.general, ansible.posix and tens of others included in Ansible.

The included collections must satisfy the collection inclusion requirements and we need to be aware of a few things related to releasing:

  • Versioning conventions: we follow SemVer to determine our specific release versions
  • Git tags: every release has an associated tag
  • Changelog presence and format: we’d like to let our users know about the changes coming out with our releases in a predictable manner

Rename the repo and change the fully qualified collection name in files (if needed)

As we are going to publish our collection on Galaxy logged-in using our personal GitHub account, we need to do some changes to our collection we created in the other post related to the Galaxy namespace which is going to be our username lowercased. If your repo name, namespace in its files and Galaxy namespace already match, skip this whole section.

1. Rename the repo in settings.

Change the my_namespace part of your collection repo name to your GitHub username lowercased, in my case it’d be andersson007:

2. Create a directory locally, change your location

$ mkdir ~/ansible_collections/andersson007
$ cd ~/ansible_collections/andersson007

3. Clone the repo:

$ git clone git@github.com:Andersson007/andersson007.my_collection.git my_collection
$ cd my_collection

4. Check out a new branch to change the namespace:

$ git checkout -b rename_namespace

5. Change the namespace in files.

Use grep recursively to find all my_collection occurrences. Change them to your GitHub username lowercased, in my case it’s andersson007.

6. Change galaxy.yml.

In galaxy.yml also change the authors, tags, repository, homepage, issues fields correspondingly, in my case it’d contain:

namespace: andersson007
name: my_collection
version: 0.1.0
readme: README.md
authors:
  - Andersson007 (github.com/Andersson007)
description: Dummy collection
license_file: LICENSE
tags:
  - dummy
repository: https://github.com/Andersson007/andersson007.my_collection
homepage: https://github.com/Andersson007/andersson007.my_collection
issues: https://github.com/Andersson007/andersson007.my_collection/issues
build_ignore:
  - .gitignore
  - changelogs/.plugin-cache.yaml

7. Commit the changes and push:

$ git commit -a -m "Change namespace"
$ git push origin rename_namespace

8. Open a pull request in the repo and merge it.

If you don’t remember how, see the previous post.

9. Check out to main locally and pull the changes we’ve just merged:

$ git checkout main
$ git pull --rebase origin main

That’s it with the namespace-related renaming.

Releasing

Let’s now release the stuff on GitHub.

1. Make sure we are in our release branch.

This is main in our case:

$ cd ~/ansible_collections/andersson007/my_collection/
$ git status
On branch main

2. Make sure the branch is up-to-date.

We usually don’t work directly in main when changing our code. As you saw in the previous post, we created a new branch from the updated local main branch, changed the code, then committed the changes and pushed the new branch to our repo, created a pull request there, and merged it to the remote main. Now let’s make our sure our local main is up-to-date.

$ git pull origin main

3. Check out a branch for changes associated with the release:

Because it’s our first release and we don’t think the collection is stable enough to be version 1.0.0, it’s gonna be 0.1.0 now.

$ git checkout -b release_0_1_0

4. Add a changelog fragment for our release.

Create the changelogs/fragments/0.1.0.yml file containing our release summary which will appear in our changelog:

release_summary: |-
  This is the first release ever of andersson007.my_collection collection.

5. Set the version field in galaxy.yml to 0.1.0.

6. Install the antsibull-changelog tool:

$ pip install antsibull-changelog

7. Generate the changelog:

$ antsibull-changelog release --reload-plugin

8. Verify the changelog:

$ cat CHANGELOG.rst
====================================================
CHANGE THIS IN changelogs/config.yaml! Release Notes
====================================================

.. contents:: Topics

v0.1.0
======

Release Summary
---------------

This is the first release ever of andersson007.my_collection collection.

New Modules
-----------

- andersson007.my_collection.dummy - A dummy module.

9. Commit the changes and push the branch to your remote repo:

$ git add .
$ git commit -a -m "Release 0.1.0 commit"
$ git push origin release_0_1_0

10. Open a pull request in the repo and merge it.

If you don’t remember how, see the previous post.

11. Check out to main locally and pull the changes we’ve just merged:

$ git checkout main
$ git pull --rebase origin main

12. Tag the commit with 0.1.0 and a message:

$ git tag -a 0.1.0 -m "andersson007.my_collection collection: version 0.1.0"

13. Push the tag to the repo

$ git push origin 0.1.0

14. Create a GitHub release using the tag

Build a collection tarball and publish it on Galaxy

15. Build a collection tarball:

$ ansible-galaxy collection build
Created collection for andersson007.my_collection at /home/aklychko/ansible_collections/andersson007/my_collection/andersson007-my_collection-0.1.0.tar.gz

16. Login to Galaxy, generate a token

17. Publish the tarball

$ ansible-galaxy collection publish andersson007-my_collection-0.1.0.tar.gz --token <TOKEN-HERE>
...
Collection has been successfully published ...

18. Remove the tarball locally from your source code directory

19. Check the collection on Galaxy

In my case the collection is now available there as galaxy.ansible.com/ui/repo/published/andersson007/my_collection/

20. The collection users can now install it using the command:

$ ansible-galaxy collection install andersson007.my_collection

There we go, we have the collection released and published!

What can you do next?

To practice, update README.md with relevant information and publish the changes in another release following the same process. Remember to be at a tagged commit when building the collection tarball.

Later, building and publishing can be automated when a new tag appear in the repo.

Any feedback is welcome in comments:) Thanks for reading!

References

6 Likes

BTW, the part

====================================================
CHANGE THIS IN changelogs/config.yaml! Release Notes
====================================================

in the generated changelog is an indication that you should edit changelogs/config.yaml and adjust the collection’s title there to something else than CHANGE THIS IN changelogs/config.yaml! :wink:

2 Likes

@Andersson007 Nice write-up! And I don’t mean to hijack your topic, do you have experience would be a sensible setup when dealing with a collection that ‘just’ does roles for the most part.

And in this particular example, I’m not talking about a ‘domain-specific’ set of roles (for example the roles shipped by community.zabbix), rather a literal collection made by a single person/organization (i.e. me) that are developed independently.

I now have a script that cobbles together the roles from their individual repos and then publishes it as a collection on Galaxy.

This works well enough for me, for now. But if someone has a better idea, please do tell! :smile:

1 Like