Provided by: pagure-doc_5.11.3+dfsg-2.1_all bug

NAME

       pagure - Pagure Documentation

       Pagure is a light-weight git-centered forge based on pygit2.

       Features:

       • Open-sources: Web-interface for the git repositories

       • Flexibility: Ability to create any project you want

       • One place: Keep your documentation and tickets in pagure

       • Collaboration: Fork a project and make a pull-request

       • Integration: Create pull-request from a fork hosted somewhere else than in pagure

       • Open  data:  Sources,  doc,  ticket and pull-requests meta-data are available in the web
         interface but also in git repos which can thus be cloned and changed locally.

       • Freedom: Pagure is fully Free and Open-Source Software!

       Resources:

       • Home pageGit repositoryGithub mirror

       Contents:

OVERVIEW

       Pagure is split over multiple components, each having their purpose and all but  two  (the
       core web application and its workers) being optional.

       These components are:

   ContentsOverviewPagure core applicationPagure workersGitolitePagure doc serverPagure milterPagure EventSource ServerPagure web-hook ServerPagure load JSON servicePagure log com service

       Before  going  into  the  overall  picture, one should realize that most of the components
       listed above are optional.

       Here is a diagram representing pagure without all the optional components:

       And here is a diagram of all the components together: .SS Pagure core application

       The core application is the flask application interacting with gitolite to provide  a  web
       UI  to  the  git  repositories  as  well  as  tickets and pull-requests.  This is the main
       application for the forge.

   Pagure workers
       Interacting with git repos can be a long process, it varies depending on the size  of  the
       repository  itself  but  also  based  on  hardware  performances or simply the load on the
       system.  To make pagure capable of handling more load, since pagure 3.0  the  interactions
       with  the  git  repositories  from  the web UI is performed by dedicated workers, allowing
       async processing of the different tasks.

       The communication between the core application and its  worker  is  based  on  celery  and
       defaults  to  using redis but any of the queueing system supported by celery could be used
       instead.

   Gitolite
       Currently pagure uses gitolite to grant or deny ssh access to  the  git  repositories,  in
       other words to grant or deny read and/or write access to the git repositories.

       Pagure  supports  cloning  over  both  ssh and http, but writing can only be done via ssh,
       through gitolite.

   Pagure doc server
       While integrated into the main application at first, it has been split  out  for  security
       concern,  displaying information directly provided by the user without a clear/safe way of
       filtering for unsafe script or hacks is a security hole.  For this reason we also strongly
       encourage  anyone  wanting  to deploy their own instance of pagure with the doc server, to
       run this application on a completely different domain name  (not  just  a  sub-domain)  in
       order to reduce the cross-site forgery risks.

       Pagure  can  be  run just fine without the doc server, all you need to do is to not define
       the variable DOC_APP_URL in the configuration file.

   Pagure milter
       The milter is a script, receiving an email as input and performing an action with it.

       In the case of pagure, the milter is used to allow replying on a comment of a ticket or  a
       pull-request  by  directly  replying  to the notification sent.  No need to go to the page
       anymore to reply to a comment someone made.

       The milter integrates with a MTA such as postfix or sendmail that you  will  have  running
       and have access to in order to change its configuration.

   Pagure EventSource Server
       Eventsource or Server Sent Events are messages sent from a server to a browser.

       For  pagure  this  technology  is  used to allow live-refreshing of a page when someone is
       viewing it. For example, while you are reading a ticket if someone  comments  on  it,  the
       comment  will  automatically  show  up  on the page without the need for you to reload the
       entire page.

       The flow is: the main pagure server does an  action,  sends  a  message  over  redis,  the
       eventsource server picks it up and send it to the browsers waiting for it, then javascript
       code is executed to refresh the page based on the information received.

   Pagure web-hook Server
       Sends notifications to third party services using POST http requests.

       This is the second notifications system in pagure with fedmsg.   These  notifications  are
       running  on  their  own  service  to prevent blocking the main web application in case the
       third part service is timing-out or just being slow.

       The flow is: the main pagure server does an  action,  sends  a  message  over  redis,  the
       web-hook  server  picks  it  up,  build  the  query  and  performs the POST request to the
       specified URLs.

   Pagure load JSON service
       The load JSON service is an async service  updating  the  database  based  on  information
       pushed  to the ticket or pull-request git repositories.  This allows updating the database
       with information pushed to the git repositories without keeping the connection  open  with
       the client.

   Pagure log com service
       The  log  com  (for  log commit) service is an async service updating the log table of the
       database on every pushed made to any  repository  allowing  to  build  the  data  for  the
       calendar heatmap graph displayed on every user's page.

USAGE

       Using  pagure  should come fairly easily, especially to people already used to forges such
       as GitHub or GitLab. There are however some tips and tricks which can be  useful  to  know
       and that this section of the doc covers.

       One  of  the  major  difference with GitHub and GitLab is that for each project on pagure,
       four git repositories are made available:

       • A git repository containing the source code, displayed in the main section of the pagure
         project.

       • A git repository for the documentation

       • A git repository for the issues and their metadata

       • A git repository for the metadata for pull-requests

       Issues  and  pull-requests  repositories  contain  the meta-data (comments, notifications,
       assignee...) from the issues and pull-request. They are are not public and only  available
       to admins and committers of the project, since they may contain private information.

       You  can  use  these repositories for offline access to your tickets or pull-requests (the
       pag-off project for example relies on a local copy of the issue git repository). They  are
       designed  to allow you to have full access to all the data about your project.  One of the
       original idea was also to allow syncing a project between  multiple  pagure  instances  by
       syncing these git repositories between the instances.

       You  can  find  the URLs to access or clone these git repositories on the overview page of
       the project. On the top right of the page, in the drop-down menu  entitled  Clone.  Beware
       that if documentation, the issue tracker or the pull-requests are disabled on the project,
       the corresponding URL will not be shown.

       Contents:

   First Steps on pagure
       When coming to pagure for the first time there are a few things one should do or check  to
       ensure all works as desired.

   Login to pagure or create your account
       Pagure has its own user account system.

       For instances of pagure such as the one at pagure.io where the authentication is delegated
       to a third party (in the case of pagure.io, the Fedora Account  System)  via  OpenID,  the
       local user account is created upon login.

       This  means,  you  cannot  be added to a group or a project before you login for the first
       time as the system will simply not know you.

       If you run your own pagure instance which uses the local authentication system,  then  you
       will find on the login page an option to create a new account.

   Upload your SSH key
       Pagure uses gitolite to manage who has read/write access to which git repository via ssh.

       An ssh key is composed of two parts:

       • a private key, which you must keep to yourself and never share with anyone.

       • a public key, which is public and therefore can be shared with anyone.

       If you have never generated a ssh key, you can do so by running:

          ssh-keygen

       or alternatively on GNOME using the application seahorse.

       This will create two files in ~/.ssh/ (~ is the symbol for your home folder).

       These  two  files will be named (for example) id_rsa and id_rsa.pub.  The first one is the
       private key that must never be shared. The second is the public key that can  be  uploaded
       on pagure to give you ssh access.

       To upload your public key onto pagure:

       1.  Login into pagure and click on the user icon on the top right corner, there, select My
       settings.

       2. In the authentication section of your user settings copy the content of your id_rsa.pub
       file in the Public SSH key text box and save your ssh key settings.  .sp NOTE:
          Pagure  supports  multiple ssh keys per user. To add more than one ssh key to your user
          account just add your new ssh key in your authentication settings (one  key  per  row),
          this way you will be able to push commits to your repository from a different computer.

   Configure the default email address
       If  the  pagure  instance  you  use  is  using  local  user authentication, you can choose
       whichever email address you prefer to use during account creation.  But in the case  (like
       pagure.io)  where  the  pagure  instance relies on an external authentication service, the
       email address provided by this service may be different from the one you prefer.

       The settings page of your account (see above for how to access the page) allows you to add
       multiple email addresses and set one as default.

       Your  default email address is the address that will be used to send you notifications and
       also as the email address in the git commit if you  merge  a  pull-request  with  a  merge
       commit.

       For  online  editing,  when doing the commit, you will be presented with the list of valid
       email addresses associated with your account and you will be able to choose which one  you
       wish to use.

       NOTE:
          All  email addresses will need to be confirmed to be activated, this is done via a link
          sent by email to the address. If you do not receive this link, don't  forget  to  check
          your spam folder!

   Forks
       A  fork in Pagure is a copy of a repository. When contributing to a project on Pagure, the
       first step is to fork it. This gives you a place to make changes to the  project  and,  if
       you so wish, contribute back to the original project.  If you're not already familiar with
       Git's distributed workflow, the Pro Git book has an excellent introduction.

       You can see a list of projects you've forked on your home page.

   Create a Fork on Pagure
       To fork a project, simply navigate to the project on Pagure and click the fork button. You
       will then be redirected to your new fork.

   Configure your Local Git Repository
       Now  that you have forked the project on Pagure, you're ready to configure a local copy of
       the repository so you can get to work. First,  clone  the  repository.  The  URL  for  the
       repository is on the right-hand side of the project overview page. For example:

          $ git clone ssh://git@pagure.io/forks/jcline/pagure.git
          $ cd pagure

       After  cloning your fork locally, it's a good idea to add the upstream repository as a git
       remote. For example:

          $ git remote add -f upstream ssh://git@pagure.io/pagure.git

       This lets you pull in changes that the upstream repository makes after you forked. Consult
       Git's documentation for more details.

   Pushing Changes
       After  you  Configure  your  Local  Git  Repository  you're ready to make your changes and
       contribute them upstream. First, start a new branch:

          $ git checkout -b my-feature-or-bugfix

       It's a good idea to give the branch a descriptive name so you can find  it  later.   Next,
       make your changes. Once you're satisfied, add the changes to Git's staging area and commit
       the changes:

          $ git add -A  # add all changes
          $ git commit -s # prepare changes for upload

       Your text editor of choice will open and you can write your commit message.  If  you  have
       not  done  so  already  Upload  your  SSH key now.  Afterwards, you are ready to push your
       changes to your remote fork:

          $ git push -u origin my-feature-or-bugfix # upload changes

       In case you cloned the repo  via  HTTP,  for  example  using  a  command  like  git  clone
       https://...,  the  push  will  fail. Pagure.io does not support pushing over HTTP. An easy
       workaround is to use:

          $ git push -u origin my-feature-or-bugfix ssh://git@pagure.io/forks/jcline/pagure.git

       You are now ready to Open a Pull Request.

   Understanding Read Only Mode of projects
       If a project is in Read Only Mode, the users of the project may not be able to modify  the
       git  repository  of  the  project. Let's say you forked a project, then the forked project
       goes into a read only mode. You won't be able to modify the git repository of  the  forked
       project  in  that  mode.   After  the read only mode is gone, you can begin to use the git
       repository again. Let's say you decide to add another user to your  fork,  this  time  the
       project  will  go  in  read  only  mode  again  but, you still will be able to use the git
       repository while the new user will have to wait for read only mode to get  over.  This  is
       also  true when you remove a user from your project. The removed user can still access the
       project's git repository, given that he had at least commit access, until  the  read  only
       mode is over.

       In  Pagure,  we  use gitolite for Access Control Lists when using SSH.  Modifying gitolite
       may be a time taking task (depending on number of projects hosted on the pagure  instance)
       that's why Pagure does it outside of HTTP Request-Response Cycle.

       Whenever  you  fork a project or add/remove a new user/group to project, gitolite needs to
       be refreshed in order to put those changes in effect for ssh based git usage.

   Actions that put the project in read only mode
       All the actions that needs gitolite to be compiled, will bring the project  in  read  only
       mode.

       • Creating/Forking a project. (only the fork will be in read only mode)

       • Adding/Removing a user/group from a project.

   HTTP PUSH
       When  using  git  push  over  http  against a pagure instance, there are two situations to
       distinguish.

   Git push over http with API token
       This is going to be the most supported approach. Any user can generate API tokens with the
       commit  ACL  which  reads in the UI as: Commit to a git repository via http(s).  These API
       tokens can be specific to a project if generated in the settings page of the  project,  or
       generic  to  all  projects if generated in the user's settings page.  In either case, they
       will no work if the user does not have at commit access to the project.

       Once the API token has been generate, the user needs to enter it with git  prompts  for  a
       password (instead of their actual password).

       For example:

          $ git push
          username: pingou
          password: ABC123...

   Git push over http with Username & Password
       This  is  only supported on pagure instance that are using the local authentication system
       (ie: where pagure manages the registration of the user accounts, email confirmation, etc).

       For these pagure instances and for these only, when being prompted by git for an  username
       and  password  the  user  can choose to enter either their username and actual password or
       their username and an API token.

   Storing the password/token
       If you interact with git regularly, typing you password or API token will  quickly  become
       tiring.   Thanksfully,  git  has a built-in mechanism named git credential store which can
       take care of this for you.

       You can use two modes for the store, either cache or  store.   -  cache  will  cache  your
       credential  in  memory  for  15  minutes  (by  default)  -  store will actually store your
       credentials in plain text on disk

       You can set this using either:

          $ git config credential.helper store
          $ git config credential.helper cache

       The timeout of the cache can be configured using:

          $ git config credential.helper 'cache --timeout=3600'

       Where the timeout value is a number of seconds (so here  the  cache  is  extended  to  one
       hour).

       Finally,  if  you  wish  to  use  this  configuration on multiple project, you can add the
       --global argument to these commands which will make the configuration work  for  all  your
       git repo instead of just the one in which you run the command.

   Pull Requests
       Pagure uses the concept of pull requests to contribute changes from your fork of a project
       back to the upstream project. To contribute a change to a project you first  open  a  pull
       request with original project. The project maintainer then merges the pull request if they
       are satisfied with the changes you have proposed.

   Open a Pull Request
       Before you can open a pull request, you need to complete the First  Steps  on  pagure  and
       Create  a  Fork  on Pagure of the project you would like to contribute to. Once you have a
       fork and you have pushed a git branch containing one or more commits,  you  are  ready  to
       contribute to the project.

   Pagure to Pagure pull request
       You can create a pull request from a pagure project, using one of the following options

   From the project overview
       1. Go the the overview tab of your fork.

       2. Locate your feature branch (Right hand side), and press the button New PR button.

       3. Fill  the  Create  a  pull  request  form  (Title and Description) and create your pull
          request.

       Notes: The New PR button appears only if there are  commits  not  available  in  the  main
       branch.  .SS From the commits history

       1. Go to the commit tab of your fork and select your feature branch.

       2. Press the create pull request button (above the latest commits).

       3. Fill  the  Create  a  pull  request  form  (Title and Description) and create your pull
          request.
       .SS From the pull requests list

       1. Go to the main project's (not your fork) pull requests list and  press  the  File  Pull
          Request button.

       2. Select the feature branch containing your changes from the dropdown menu.

       3. Fill  the  Create  a  pull  request  form  (Title and Description) and create your pull
          request.
       .SS Remote Git to Pagure pull request

       You can create a pull request from another git hosting  platform  (e.g.  GitHub,  GitLab).
       This is a remote pull request.

   From the pull requests list
       1. Go  to  the  main  project's (not your fork) pull requests list and press the File Pull
          Request button.

       2. Select the Remote pull-request option from the dropdown menu.

       3. Fill the New remote pull-request form (Title, Git repo  address  and  Git  branch)  and
          create your remote pull request.

       Congratulations!  It is now up to the project maintainer to accept your changes by merging
       them.

   Updating Your Pull Request
       It is likely that project maintainers will  request  changes  to  your  proposed  code  by
       commenting  on  your pull request. Don't be discouraged! This is an opportunity to improve
       your contribution and for both reviewer and reviewee to become better programmers.

       Adding to your pull request is as simple as pushing new commits to the branch you used  to
       create  the pull request. These will automatically be displayed in the commit list for the
       pull request.

   Rebasing
       You may encounter a situation where you want to include changes  from  the  master  branch
       that  were made after you created your pull request. You can do this by rebasing your pull
       request branch and pushing it to your remote fork.

   Working with Pull Requests
       It's quite common to work with a pull request locally, either to build on top of it or  to
       test  it.  You can do this easily using git fetch to download the pull request followed by
       git checkout to work with it as you would any local branch.  The syntax for git fetch is:

          git fetch $REMOTE pull/$PR_NUMBER/head:$BRANCHNAME

       For example, if you have PR#1 which "adds support for foo" you might run:

          git fetch origin pull/1/head:add-foo-support

       Then you can work with the add-foo-support normally:

          git checkout add-foo-support

       NOTE:
          You may use / characters in your branch name if you want to group your pull requests by
          the  submitter  name,  bug  number, etc.  For example, you could name your local branch
          user/add-foo-support.

       If you want to allow working with all of your pull requests locally,  you  can  do  so  by
       editing  your  git  configuration as follows.  Locate your remote in the .git/config file,
       for example:

          [remote "origin"]
              url = ssh://git@pagure.io/pagure.git
              fetch = +refs/heads/*:refs/remotes/origin/*

       Now add this line:

          fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

       to that section as the first fetch line, like this:

          [remote "origin"]
              url = ssh://git@pagure.io/pagure.git
              fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
              fetch = +refs/heads/*:refs/remotes/origin/*

       Obviously, the remote URL should be matching the URL of your project  (pagure  project  in
       this example).

       Now you can fetch the all the pull requests:

          $ git fetch origin
          From ssh://pagure.io/pagure
          * [new ref]        refs/pull/2541/head -> origin/pr/2541
          * [new ref]        refs/pull/2540/head -> origin/pr/2540
          * [new ref]        refs/pull/2538/head -> origin/pr/2538

       To checkout a particular pull request:

          $ git checkout pr/25413
          Branch pr/2541 set up to track remote branch pr/2541 from origin.
          Switched to a new branch 'pr/2541'

       You will now be able to use this branch to work from or on this pull requests.

       If you are only interested in one particular pull request and do not want to fetch all the
       project PRs, you can add to your ~/.bashrc the following function:

          function pullpr {
              remote="${2:-origin}"
              git fetch $remote pull/$1/head:pr_$1
              git checkout pr_$1
          }

       Then after sourcing your ~/.bashrc or restarting  your  shell,  you  can  use  the  pullpr
       function  to  checkout  a  pull  request from within the clone of the git repository.  For
       example checkout pull request number 58  from  current  git  clone  (here  the  infra-docs
       project)

          $ source ~/.bashrc
          $ pullpr 58
          remote: Counting objects: 393, done.
          remote: Compressing objects: 100% (238/238), done.
          remote: Total 365 (delta 231), reused 255 (delta 127)
          Receiving objects: 100% (365/365), 71.36 KiB | 63.00 KiB/s, done.
          Resolving deltas: 100% (231/231), completed with 20 local objects.
          From ssh://pagure.io/infra-docs
          * [new ref]         refs/pull/58/head -> pr_58
          Switched to branch 'pr_58'

   Using Markdown in Pagure
       Pagure  uses  Markdown  syntax highlighting as the base for formatting comments in issues,
       pull requests, and in Markdown files in repositories. For basic formatting, Pagure follows
       common  Markdown  formatting,  but  it  also  has  some  unique  syntax  for more advanced
       formatting. This help page helps demonstrate how to use Markdown in Pagure.

       Pagure relies on the Markdown python module to do the conversion.  It has  enabled  a  few
       extensions:

       • Definition ListsFenced Code BlocksTablesSmart StrongAdmonitionCodeHiliteSane lists

       README files can also rely on:

       • AbbreviationsFootnotesTable of Contents

       While comments use:

       • New Line to Break

       WARNING:
          Pagure  does not support linking to remote images, if you want to link to an image on a
          ticket, you will have to upload it to pagure.

   Styling
       You can mark up text with bold, italics, or strikethrough.

       •

         Style: Bold

                • Syntax: ** ** or __ __

                • Example: **This is bold text**

                • Output: This is bold textStyle: Italics

                • Syntax: * * or _ _

                • Example: _This is italicized text_

                • Output: This is italicized textStyle: Strikethrough

                • Syntax: ~~ ~~

                • Example: ~~This text is no longer relevant~~

                • Output: This text is no longer relevant

       •

         Style: Bold and italics

                • Syntax: ** ** and _ _

                • Example: ** This text is the _most important thing ever_ **

                • Output: ** This text is the most important thing ever **

   Quoting
       You can show text as being quoted with the > character.

          Before merging this pull request, remember Clark Kent mentioned this:
          > Double-check there's no reference to the Kryptonite library in the program since we removed that a few versions ago.

       Before merging this pull request, remember Clark Kent mentioned this:
          Double-check there's no reference to the Kryptonite library in  the  program  since  we
          removed that a few versions ago.

       You can also make a line-wrapping blockquote using <br/>.

          Remember what Solomon said:
          > I don't want to survive. <br/> I want to live.

       Remember what Solomon said:
          I don't want to survive.

          I want to live.

       For more details regarding Blockquote, refer Blockquote.

   Code
       You  can  highlight  parts of a line as code or create entire code blocks in your Markdown
       documents. You can do this with the backtick character (`).  Text inside of backticks will
       not be formatted.

          When running the program for the first time, use `superman --initialize`.

       When running the program for the first time, use superman --initialize.

       To format multiple lines of code into its own block, you can wrap the text block with four
       tilde (~) characters

          Install the needed system libraries:
          `~~~~`
          sudo dnf install git python-virtualenv libgit2-devel \
                          libjpeg-devel gcc libffi-devel redhat-rpm-config
          `~~~~`

       Install the needed system libraries:

          sudo dnf install git python-virtualenv libgit2-devel \
                       libjpeg-devel gcc libffi-devel redhat-rpm-config

   Hyperlinks
   Regular links
       Need to embed a link to somewhere else? No problem! You can  create  an  in-line  link  by
       wrapping the text in [ ] and appending the URL in parentheses ( ) immediately after.

       Pagure is used by the [Fedora Project](https://fedoraproject.org).

       Pagure is used by the Fedora Project.

   Links to ticket/PR of the same project
       You  want  to  link  to a ticket or a pull-request in the current project? Easy just use #
       immediately followed by the identifier of the ticket or pull-request.

       This is an example for #2921

       This is an example for #2921

   Links to ticket/PR of another project
       You want to link to a ticket or a pull-request of a  different  project?  Simply  add  the
       project name in front of the # and immediately followed by the identifier of the ticket or
       pull-request.

       This is an example for pagure#2921

       This is an example for pagure#2921

   Lists
   Unordered lists
       You can make unordered lists spanning multiple lines with either - or *.

          * Superman
          * Batman
              * Protector of Gotham City!
          * Superwoman
          * Harley Quinn
              * Something on this list is unlike the others...

       • Superman

       •

         Batman

                • Protector of Gotham City!

       • Superwoman

       •

         Harley Quinn

                • Something on this list is unlike the others...

   Ordered lists
       You can make ordered lists by preceding each line with a number.

          1. Superman
          2. Batman
              1. Protector of Gotham City!
              2. He drives the Batmobile!
          3. Superwoman
          4. Harley Quinn
              1. Something on this list is unlike the others...
              2. Somebody evil lurks on this list!

       1. Superman

       2.

          Batman

                 1. Protector of Gotham City!

                 2. He drives the Batmobile!

       3. Superwoman

       4.

          Harley Quinn

                 1. Something on this list is unlike the others...

                 2. Somebody evil lurks on this list!

   Tagging users
       You can tag other users on Pagure to send them a  notification  about  an  issue  or  pull
       request.  To tag a user, use the @ symbol followed by their username.  Typing the @ symbol
       in a comment will bring up a list of users that match the username. The list  searches  as
       you  type.  Once  you  see the name of the person you are looking for, you can click their
       name to automatically complete the tag.

       @jflory7, could you please review this pull request and leave feedback?

       @jflory7, could you please review this pull request and leave feedback?

   Tagging issues or pull requests
       In a comment, you can automatically link a pull request or issue by its number.   To  link
       it,  use  the  #  character  followed  by its number. Like with tagging users, Pagure will
       provide suggestions for issues or pull requests as you type the number. You can select the
       issue in the drop-down to automatically tag the issue or pull request.

       If  you  need  to tag an issue or pull request that is outside of the current project, you
       are also able to do this. For cross-projects links, you can tag them  by  typing  <project
       name>#id or <username>/<project name>#id.

   Emoji
       Pagure  natively  supports  emoji characters. To use emoji, you can use two colons wrapped
       around the emoji keyword (:emoji:). Typing a colon by itself  will  bring  up  a  list  of
       suggested  emoji  with  a  small  preview. If you see the one you are looking for, you can
       click it to automatically complete the emoji.

       I reviewed the PR and it looks good to me. :+1: Good to merge! :clapper:

       I reviewed the PR and it looks good to me. 👍 Good to merge! 🎬

   Improve this documentation!
       Notice anything that can be improved in this  documentation?  Find  a  mistake?   You  can
       improve this page! Find it in the official Pagure repository.

   Project settings
       Each  project  have  a  number  of options that can be tweaked in the settings page of the
       project which is accessible to the person having full commits to the project.

       This page presents the different settings and there effect.

   Always merge
       This Boolean enables or disables always making a merge commit when merging a pull-request.

       When merging a pull-request in pagure there are three states:

       • fast-forward: when the commits in the pull-request can be fast-forwarded pagure  signals
         it and just fast-forward the commit, keeping the history linear.

       • merge:  when  the  commits  in the pull-request cannot be merged without a merge commit,
         pagure signals it and performs this merge commit.

       • conflicts: when the commits in the pull-request cannot be merged  at  all  automatically
         due to one or more conflicts. Then pagure signals it and prevent merging.

       If  the Always merge option is on, then the fast-forward option above is disabled in favor
       of the merge option.

   Comment editing
       This Boolean enables or disables editing comments.

       After commenting on a ticket or a pull-request, the admins of the project and  the  author
       of the comment may be allowed to edit the comment.  This allows them to adjust the wording
       or the style as they wish.

       NOTE:
          notification about a comment  is  only  sent  once  with  the  original  text,  changes
          performed later will not trigger a new notification.

       Some  project  may  not  want  to  allow  editing comments after they were posted and this
       setting allows turning it on or off.

   Enforce signed-off commits in pull-request
       This Boolean enables or disables checking for a 'Signed-off-by' line (case insensitive) in
       the commit messages of the pull-requests.

       If  this  line  is  missing, pagure will display a message near the Merge button, allowing
       project admin to request the PR to be updated.

       NOTE:
          This setting does not prevent commits without this 'signed-off-by' line  to  be  pushed
          directly, it only work at the pull-request level.

   Issue tracker
       This  Boolean simply enables or disables the issue tracker for the project.  So if you are
       tracking your ticket on a different system, you can  simply  disable  reporting  issue  on
       pagure by un-checking this option.

   Minimum score to merge pull-request
       This  option  can be used for project wishing to enforce having a minimum number of people
       reviewing a pull-request before it can be merged.

       If this option is enabled, anyone can vote in favor or against a pull-request and the  sum
       of  the  votes  in  favor minus the sum of the votes against give the pull-request a score
       that should be equal or greater than the value entered in this option for the pull-request
       to be allowed to be merged.

       NOTE:
          Only  the  main  comments  (i.e.:  not in-line) are taken into account to calculate the
          score of the pull-request.

       To vote in favor of a pull-request, use either: * +1 * :thumbsup:

       To vote against a pull-request, use either: * -1 * :thumbsdown:

       NOTE:
          Pull-Request not reaching the minimum score are not automatically merged

       NOTE:
          Anyone can vote on the pull-request, not only the contributors.

       NOTE:
          Only one vote per person is taken into account to compute the final score.

   Only assignee can merge pull-request
       This option can be used for project wishing to institute a strong  review  workflow  where
       pull-request are first assigned then merged.

       If this option is enabled, only the person assigned to the pull-request can merge it.

   Project documentation
       Pagure  offers  the  option to have a git repository specific for the documentation of the
       project.

       This repository is then accessible under the Docs tab in the menu of the project.

       If you prefer to store your documentation elsewhere or maybe even within  the  sources  of
       the project, you can disable the Docs tab by un-checking this option.

   Pull requests
       Pagure  offers the option to fork a project, make changes to it and then ask the developer
       to merge these changes into the project. This is similar to the pull-request mechanism  on
       GitHub or GitLab.

       However,  some projects may prefer receiving patches by email on their list or via another
       hosting platform or simply  do  not  wish  to  use  the  pull-request  mechanism  at  all.
       Un-checking  this option will therefore prevent anyone from opening a pull-request against
       this project.

       NOTE:
          disabling pull-requests does not disable forking the projects.

   Web-hooks
       Pagure offers the option of sending notification about event happening on  a  project  via
       [web-hooks|https://en.wikipedia.org/wiki/Webhook].  This  option is off by default and can
       be turned on for a pagure instance in its configuration file.

       The URL of the web-hooks can be entered in this field.

       NOTE:
          See the notifications documentation to learn more about web-hooks in pagure and how  to
          use them.

   Tags
       Pagure  allows  you to define "tags" that can be added to Issues.  Tags are unique to each
       project, and they can only be defined in the project settings page.   The  Tag  color  can
       also be customized for a more robust visual representation of the tag.

   Deploy keys
       Deploy  keys  are  SSH  keys that have access to pull/push only to a single project.  Upon
       creation, admins can determine whether  this  particular  key  has  read/write  access  or
       read-only.

   Project Level Access Control
       Till  release  2.12,  pagure had a very simple user model. If we added a new user or a new
       group to a project, the user/group would be an  admin  of  the  project.   The  user/group
       could do everything from changing the status of an issue to adding or removing any user on
       the project. With project ACL feature, we allow a more fine grained control  over  what  a
       new user/group has access to, what things it can add or what actions it can take.

       With Project ACL feature, We can now have three levels of access:

       • Ticket:  A user or a group with this level of access can only edit metadata of an issue.
         This includes  changing  the  status  of  an  issue,  adding/removing  tags  from  them,
         adding/removing  assignees  and  every other option which can be accessed when you click
         "Edit Metadata" button in an issue page. However, this user can not "create" a  new  tag
         or  "delete"  an existing tag because, that would involve access to settings page of the
         project which this user won't have. It also won't be able to "delete" the issue because,
         it falls outside of "Edit Metadata".

       • Commit:  A user or a group with this level of access can do everything what a user/group
         with ticket access can do + it can do everything on the project  which  doesn't  include
         access to settings page. It can "Edit Metadata" of an issue just like a user with ticket
         access would do, can merge a pull request, can push to  the  main  repository  directly,
         delete an issue, cancel a pull request etc.

       • Admin: The user/group with this access has access to everything on the project.  All the
         "users" of the project that have been added till now are having this access.   They  can
         change the settings of the project, add/remove users/groups on the project.

   Add/Update Access
       • Every  time  you  add  a  new  user  or a new group to the project, you will be asked to
         provide the level of access you want to give to that user  or  group.  It's  a  required
         field in the form.

       • To  add  a  user  or a group to a project, go to settings page of the project. There are
         buttons with text: Add User and Add Group. It will take you to a  different  page  where
         you  will have to select the user or group (depending on whether you clicked Add User or
         Add Group) and the access you want the user/group to have.

       • If you want to update a user or a group's access, go to settings page  of  the  project.
         There  is  a  section  which lists users associated with the project with the buttons to
         edit their access and a different button to remove them from the project. If  you  click
         the  edit  button, you will be taken to a different page where you can change the access
         and then click on Update button.

   Points to be noted
       • The creator of a project in pagure holds a more unique position than a normal user  with
         admin  access.  The  creator can not be removed by an admin. His access level can not be
         changed. But, an admin's access can be updated by a fellow admin or the creator himself.

       • All the members of a group will have same access over the project except  for  the  case
         mentioned in the next point.

       • In  cases  when, a user is added to a project with an access level of "A" and a group is
         also added to the same project with access level "B" and that user is  also  present  in
         the group then, the user will enjoy the access of higher of "A" and "B". Meaning, if the
         user earlier had access of ticket and the group had access  of  commit,  the  user  will
         enjoy  the  access of a committer. And, if the user earlier had access of commit and the
         group had access of ticket, the user will still be a committer.

   Using the roadmap feature
       Pagure allows building the roadmap of the project using the tickets and their milestones.

       The principal is as follow:

       • For each milestones defined in the settings of  the  project,  the  roadmap  will  group
         tickets with the corresponding milestone.

       • If  your  project has an unplanned milestone, this milestone will be shown at the bottom
         of the roadmap page. This allowing you to put something on the roadmap without assigning
         a real milestone to it.

   Example
       For a project named test on pagure.io.

       • First,  go  to  the  settings  page  of the project, create the milestones you like, for
         example: v1.0 and v2.0.

       • For the tickets you want to be on these milestones, go through  each  of  them  and  set
         their  milestone  to  either  v1.0  or v2.0, or none of them if the ticket is not on the
         roadmap.  You can set the milestone on the metadata panel on the right side of the issue
         page.

       • And this is how it will look like
       .SS Flags

       Pagure  offers  the  possibility  to flag pull-requests and commits. A flag is a way for a
       third-party tool to provide feedback on a pull-request or a commit.

       This feedback can be as simple as the outcome of running the tests, or some lint tool,  or
       test coverage evolution.

   Add a flag
       Flags  can  be  set  via  the  API,  see  the  /api/  URL  in  your  pagure instance or at
       pagure.io/api/ and look for the endpoints with  the  titles:  Flag  a  commit  or  Flag  a
       pull-request.

       • uid:  the  API  endpoints  to  add  flag  have  an optional UID argument. It is a unique
         identifier (of maximum 32 characters) that is unique the commit or pull-request that  is
         being/has  been  flagged.   If  it is not specified by the user/tool adding the flag, it
         will be automatically generated and in either case, will be returned in  the  JSON  data
         returned  by  the  API  endpoints.  Note that this is the only time you would be able to
         retrieve this identifier if you do not specify it yourself.

       • status: this field indicates the status of the task in the  system  running  it.  Pagure
         supports the following statuses:

         • success: the task ended successfully.

         • canceled: the task was canceled.

         • failure: the task ended but failed.

         • error: the task did not end at all.

         • pending:  the  results  of  this task are pending.  (for failure vs error think of the
           test system ran the tests but they failed vs the test system did not get  to  run  the
           tests)

       • percent:  this is an optional field which can be used to provide some more details about
         the outcome of the task. For example this could be used for test coverage, or the number
         of test that failed/passed.

       • username:  the  name  of  the  system  running  the tests. While not being restricted in
         length, a shorter name will render better in the interface.

       • comment: a free text form not restricted in length (however, here as well if the comment
         is too long it may render off in the interface).

       • url:  the  URL  the flag is linked to and where the user should be able to retrieve more
         information about the task and its outcome.

   Example of two flags on a commit:
       .SS Example of two flags on a pull-request: .SS Magic Words

       Magic words are words and constructs you can use in your commit message to make pagure act
       on tickets or pull-requests.

   Enabling magic words
       These  magic  words  are  enabled  if  the pagure git hook is enable. To do so, go to your
       project's settings page, open the Hooks tab and activate there the Pagure hook.

   Using magic words
       To reference an issue/PR you need  to  use  one  of  recognized  keywords  followed  by  a
       reference  to  the  issue  or  PR,  separated  by whitespace and and optional colon.  Such
       references can be either:

       • The issue/PR number preceded by the # symbol

       • The full URL of the issue or PR

       If using the full URL, it is possible to reference issues in other projects.

       The recognized keywords are:

       • fix/fixed/fixes

       • relate/related/relates

       • merge/merges/merged

       • close/closes/closed

       • resolve/resolves/resolved

       Examples:

       • Fixes #21

       • related: https://pagure.io/myproject/issue/32

       • this commit merges #74

       • Merged: https://pagure.io/myproject/pull-request/74

       Capitalization does not matter; neither does the colon (:) between keyword and number.

   Using the doc repository of your project
       In this section of the documentation, we are interested in the doc repository.

       The doc repository is a simple Git repo. It can be displayed as a subfolder of  a  project
       or as a dedicated Git repo.  Either way its content can be displayed in 2 ways:

       • inline under the Docs tab in Pagure:

         • https://pagure.io/docs/<project>/ or

         • https://pagure.io/docs/<namespace>/<project>/

       • standalone:

         • https://docs.pagure.org/<project>/ or

         • https://docs.pagure.org/<namespace>.<project>/

       By  default  the  Docs  tab  in the project's menu is disabled, you will have to visit the
       project's settings page and turn it on in the Project options section.

       The URL to clone the doc repo is:

       • https://pagure.io/docs/<namespace>/<project>.git

       To view the doc source files in the browser:

       • if the doc repo is kept in the project's sources, use the project's website

       • if the doc repo is a dedicated repo, use https://pagure.io/<namespace>/<name>

       Different file types can be used for your documentation in this repo:

       • simple text files

         Pagure will display them as plain text. If one of  these  is  named  index  it  will  be
         presented as the front page.

       • RST or markdown files

         Pagure  will  convert  them  to HTML on the fly and display them as such.  The RST files
         must end with .rst and the markdown ones must end with .mk, .md or simply .markdown.

       • HTML files

         Pagure will simply show them as such.

       Updating documentation hosted in a dedicated repo is like using other repos.

   Example
       Pagure's documentation is kept in pagure's sources, in the doc folder there.  You can  see
       it  at:  https://pagure.io/pagure/blob/master/f/doc.  This doc can be built with Sphinx to
       make it HTML and prettier.

       The built documentation is available at: https://docs.pagure.org/pagure/.

       This is how it is built/updated:

       • Clone pagure's sources:

            git clone https://pagure.io/pagure.git

       • Move into its doc folder:

            cd pagure/doc

       • Build the doc:

            make html

       • Clone pagure's doc repository:

            git clone ssh://git@pagure.io/docs/pagure.git

       • Copy the result of sphinx's build to the doc repo:

            cp -r _build/html/* pagure/

       • Go into the doc repo and update it:

            cd pagure
            git add .
            git commit -am "Update documentation"
            git push

       • Clean the sources:

            cd ..
            rm -rf pagure  # remove the doc repo
            rm -rf _build  # remove the output from the sphinx's build

       To make things simpler, the following script (name update_doc.sh) can be used:

          #!/bin/bash

          make html

          git clone "ssh://git@pagure.io/docs/$1.git"
          cp -r _build/html/* $1/
          (
              cd $1
              git add .
              git commit -av
              git push
          )

          rm -rfI _build
          rm -rfI $1

       It can be used by running update_doc.sh <project> from within the  folder  containing  the
       doc.

       So for pagure it would be something like:

          cd pagure/doc
          update_doc.sh pagure

   Using web-hooks
       Web-hooks  are  a  notification  system  that could be compared to a callback.  Basically,
       pagure will make a HTTP POST request to one or more third  party  server/application  with
       information about what is or just happened.

   Activating web-hooks notifications
       To  set-up a web-hook, simply go to the settings page of your project and enter the URL to
       the server/endpoint that will receive the notifications.  If you wish  to  enter  multiple
       URLs, enter one per line.  To stop all notifications, clear out that field.

       Pagure  will  send  a  notification  to  this/these  URL(s)  for every action made on this
       project: new issue, new pull-request, new comments, new commits...

       NOTE:
          The notifications sent via web-hooks have the same payload as  the  notifications  sent
          via  fedmsg.   Therefore,  the list of pagure topics as well as example messages can be
          found in the fedmsg documentation about pagure

   Authenticating the notifications
       There is, in the settings page, a web-hook key which is used by the server  (here  pagure)
       to  sign  the  message sent and which you can use to ensure the notifications received are
       coming from the right source.

       Each POST request made contains some specific headers:

          X-Pagure
          X-Pagure-Project
          X-Pagure-Signature
          X-Pagure-Signature-256
          X-Pagure-Topic

       X-Pagure contains URL of the pagure instance sending this notification.

       X-Pagure-Project contains the name of the project on that pagure instance.

       X-Pagure-Signature contains the signature of  the  message  allowing  to  check  that  the
       message comes from pagure.

       X-Pagure-Signature-256  contains  the  SHA-256  signature of the message allowing to check
       that the message comes from pagure.

       NOTE:
          These headers are present to allow you to verify that the webhook was actually sent  by
          the correct Pagure instance. These are not included in the signed data.

       X-Pagure-Topic  is  a  global  header  giving  a  clue  about the type of action that just
       occurred. For example issue.edit.

       WARNING:
          The headers X-Pagure, X-Pagure-Project and X-Pagure-Topic are present  for  convenience
          only,  they  are  not  signed  and therefore should not be trusted. Rely on the payload
          after checking the signature to make any decision.

       Pagure relies on hmac to sign the content of its messages. If you  want  to  validate  the
       message, in python, you can do something like the following:

          import hmac
          import hashlib

          payload =  # content you received in the POST request
          headers =  # headers of the POST request
          project_web_hook_key =  # private web-hook key of the project

          hashhex = hmac.new(
              str(project_web_hook_key), payload, hashlib.sha1).hexdigest()

          if hashhex != headers.get('X-Pagure-Signature'):
              raise Exception('Message received with an invalid signature')

   Templates for ticket input
       Pagure  offers the possibility to add templates for ticket's input. These templates do not
       enforce anything, users will have the possibility to simply ignore  it,  or  even  to  not
       follow  it,  but  it  also  helps  structuring  the  ticket  opened  against a project and
       highlighting the information that are often requested/needed.

       The templates are provided in the git repository containing the meta-data for the tickets.
       They  must  be placed under a templates folder in this git repository, end with .md and as
       the extension suggests can be formatted as markdown.

       If you create a template templates/default.md, it will be shown by  default  when  someone
       ask to create a new ticket.

   Example
       For a project named test on pagure.io.

       • First, clone the ticket git repo [1] and move into it

          git clone ssh://git@pagure.io/tickets/test.git
          cd test

       • Create the templates folder

          mkdir templates

       • Create a default template

          vim templates/default.md

       And place in this file the following content:

          ##### Issue

          ##### Steps to reproduce
          1.
          2.
          3.

          ##### Actual results

          ##### Expected results

       • Commit and push the changes to the git repo

          git add templates
          git commit -m "Add a default template for tickets"
          git push

       • And this is how it will look like

       [1]  The  URLs  to  the  different  git  repositories can be found on the main page of the
            project, on the right-side menu, under the section Source GIT URLs. Click on more  to
            see  them  if  you  are  logged  in and have access to the repository (the ticket and
            request git repositories require a commit access or higher).

   Customize the PR page
       Pagure offers the possibility to customize the page that creates pull-request to add  your
       specific  information,  such  as:  please  follow  the  XYZ coding style, run the tests or
       whatever you wish to inform contributors when they open a new pull-request.

       The customization is done via a file in the git repository containing  the  meta-data  for
       the  pull-requests.  This  file  must  be  placed  under  a  templates  folder,  be  named
       contributing.md and can be formatted as you wish using markdown.

   Example
       For a project named test on pagure.io.

       • First, clone the pull-request git repo [1] and move into it

          git clone ssh://git@pagure.io/requests/test.git
          cd test

       • Create the templates folder

          mkdir templates

       • Create the customized PR info

          vim templates/contributing.md

       And place in this file the following content:

          Contributing to test
          ====================

          When creating a pull-request against test, there are couple of items to do
          that will speed up the review process:

          * Ensure the unit-tests are all passing (cf the ``runtests.py`` script at the
            top level of the sources)
          * Check if your changes are [pep8](https://www.python.org/dev/peps/pep-0008/)
            compliant for this you can install ``python-pep8`` and run the ``pep8`` CLI
            tool

       • Commit and push the changes to the git repo

          git add templates
          git commit -m "Customize the PR page"
          git push

       • And this is how it will look like

       [1]  All the URLs to the different git repositories can be found on the main page  of  the
            project,  on the right-side menu, under the section Source GIT URLs, click on more to
            see them.

   Theming Guide
       Pagure is built on Flask, and uses Jinja2 for templates. Pagure also includes the  ability
       to  apply  different themes that control the look and feel of your pagure instance, or add
       or remove elements from the interface.

   Setting a theme
       The theme is set in the Pagure configuration file. The theme name is defined by  the  name
       of the directory in the /themes/ folder that contains the theme. For example to enable the
       theme that is used on Pagure.io, add the following line to your Pagure configuration:

          THEME = "pagureio"

   Theme contents
       A theme requires two directories (templates and static) in the directory that contains the
       theme.  The  only  other  required  file  is  theme.html  which is placed in the templates
       directory

   templates/
       The  templates  directory  is  where  pagure  will  look  for  the  theme.html   template.
       Additionally,  if  you  wish  to  override  any  template in Pagure, place it in the theme
       templates/ directory, and pagure will use that template rather than the standard one.

       WARNING:
          Take care when overriding templates, as any changes to Pagure upstream will need to  be
          backported to your theme template override.

   static/
       The  static directory contains all the static elements for the theme, including additional
       a favicon, images, Javascript, and CSS files. To reference a  file  in  the  theme  static
       directory  use  the  jinja2  tag  {{  url_for('theme.static',  filename='filename')}}. For
       example:

          <link href="{{ url_for('theme.static', filename='theme.css') }}"
                rel="stylesheet" type="text/css" />

   templates/theme.html
       The theme.html file defines a subset of items in the Pagure interface  that  are  commonly
       changed  when  creating  a  new  theme. Theming is a new feature in Pagure, so this set is
       currently small, but please file issues or PRs against pagure with ideas of new  items  to
       include.

       The current items configurable in theme.html are:

   masthead_class variable
       A  string  of  additional  CSS  class(es)  to be added to the navbar element.  This navbar
       element is the topbar in Pagure. For example:

          {% set masthead_class = "navbar-dark bg-dark" %}

   masthead_navbar_items() macro
       A Jinja macro that allows themes to inject custom items  in  the  Pagure  navigation  bar.
       Example:

          {% macro masthead_navbar_items() %}
              <li class="nav-item ml-3">
                  <a class="nav-link font-weight-bold" href="...">
                      Foobar
                  </a>
              </li>
          {% endmacro %}

   site_title variable
       A  string  containing the text to append at the end of the html title on every page on the
       site. Usage:

          {% set site_title = "Pagure" %}

   projectstring(Bool:plural) macro
       A macro that returns a string used to refer to Projects in  Pagure  The  plural  parameter
       informs if the string to be returned is the plural form.  This macro is optional.  Usage:

          {% macro projectstring(plural=False) -%}
              {% if plural %}
                  Repositories
              {% else %}
                  Repository
              {% endif %}
          {% endmacro -%}

   projecticon variable
       A string containing the name of the fontawesome icon to use for Projects. This variable is
       optional. Usage:

          {% set projecticon = "Package" %}

   head_imports() macro
       A Jinja macro that defines the additional items in the html head to be imported. The  base
       templates  do not include the bootstrap CSS, so this needs to be included in this macro in
       your theme. Additionally, include your favicon here, and a  link  to  any  additional  CSS
       files your theme uses. Example:

          {% macro head_imports() %}
              <link rel="shortcut icon" type="image/vnd.microsoft.icon"
                    href="{{ url_for('theme.static', filename='favicon.ico')}}"/>
              <link rel="stylesheet" href="{{ url_for('theme.static', filename='bootstrap/bootstrap.min.css')}}" />
              <link href="{{ url_for('theme.static', filename='theme.css') }}" rel="stylesheet" type="text/css" />
          {% endmacro %}

   js_imports() macro
       A  Jinja  macro  that  defines  the  additional  javascript files to be imported. The base
       templates do not include the bootstrap JS, so this needs to be included in this  macro  in
       your theme. Example:

          {% macro js_imports() %}
              <script src="{{ url_for('theme.static', filename='bootstrap/bootstrap.bundle.min.js')}}"></script>
          {% endmacro %}

   browseheader_message(select) macro
       An  optional  Jinja macro that defines the welcome message that is shown above the tabs on
       the Browse Pages (Projects, Users, and Groups). The select parameter is a string with  the
       name of the page being shown Example:

          {% macro browseheader_message(select) %}
              {% if select == 'projects' %}
              <div class="row justify-content-around">
              <div class="col-md-8">
                  <div class="jumbotron bg-transparent m-0 py-4 text-center">
                      <h1 class="display-5">Welcome to my Pagure</h1>
                      <p class="lead">Pagure is an Open Source software code hosting system.</p>
                  </div>
              </div>
              </div>
              {% endif %}
          {% endmacro %}

   footer() macro
       A Jinja macro that defines the footer of the Pagure site. Example:

          {% macro footer() %}
              <div class="footer py-3 bg-light border-top text-center">
                  <div class="container">
                      <p class="text-muted credit">
                  Powered by
                  <a href="https://pagure.io/pagure">Pagure</a>
                  {{ g.version }}
                      </p>
                      <p><a href="{{ url_for('ui_ns.ssh_hostkey') }}">SSH Hostkey/Fingerprint</a> | <a href="https://docs.pagure.org/pagure/usage/index.html">Documentation</a></p>
                  </div>
              </div>
          {% endmacro %}

   about_page() macro
       A  Jinja  macro  that defines the content of the About page (available at /about). You may
       want to replace the links to contact links for your own instance. Example:

          {% macro about_page() %}
              <div class="container mt-5">
                  <h1>About</h1>
                  <p>This is an instance of Pagure, a git forge.</p>
                  <p>If you experience a bug or security concern, please <a href="https://pagure.io/pagure/issues">submit an issue</a>.</p>
                  <p>You may also post questions to the Pagure Development list by emailing: <a href="mailto:pagure-devel@lists.pagure.io">pagure-devel@lists.pagure.io</a> or <a href="https://lists.pagure.io/admin/lists/pagure-devel.lists.pagure.io/">subscribe to the list</a>.</p>
                  <p><a href="https://lists.pagure.io/admin/lists/pagure-announce.lists.pagure.io/">Subscribe to announcements</a> about Pagure.</p>
              </div>
          {% endmacro %}

   Upgrade a database
       For changes to the database schema, we rely on Alembic.  This allows us to do upgrade  and
       downgrade of schema migration, kind of like one would do commits in a system like git.

       To upgrade the database to the latest version simply run:

          alembic upgrade head

       NOTE:
          if pagure's configuration file isn't in /etc/pagure/pagure.cfg you will have to specify
          it to alembic using the command:

              PAGURE_CONFIG=/path/to/pagure.cfg alembic upgrade head

          This allow applies for the command specified below.

       This may fail for different reasons:

       • The change was already made in the database

       This can be because the version of the database schema saved  is  incorrect.   It  can  be
       debugged using the following commands:

          • Find the current revision:

                alembic current

          • See the entire history:

                alembic history

       Once  the  revision  at  which  your  database should be is found (in the history) you can
       declare that your database is at this given revision using:

          alembic stamp <revision id>

       Eventually, if you do not know where your  database  is  or  should  be,  you  can  do  an
       iterative  process  stamping the database for every revision, one by one trying every time
       to alembic upgrade until it works.

       • The database used does not support some of the changes

       SQLite is handy for development but does not support all the features of a  real  database
       server.  Upgrading  a  SQLite  database might therefore not work, depending on the changes
       done.

       In some cases, if you are using a SQLite database, you will have to destroy it and  create
       a new one.

   Pagure CI
       Pagure  CI  is  a service integrating the results of Continuous Integration (CI) services,
       such as jenkins or travis-ci, into pull-requests opened against your project on pagure.

       NOTE:
          By default pagure-ci is off, an admin of your pagure instance will need to configure it
          to support one or more CI services. Check the configuration section on how to do that.

       Contents:

   Jenkins with Pagure-ci
       Jenkins  is  a Continuous Integration service that can be configured to be integrated with
       pagure.

       This document describe the steps needed to make it work.

   How does it work?
       The principal is:

       • pagure will trigger a build on jenkins when a pull-request is created, updated  or  when
         someone  explicitly asks pagure to do so or when a new commit is pushed (if pagure-ci is
         configured to trigger on commit).

       • pagure will send a few information to jenkins when triggering  a  build:  REPO,  BRANCH,
         BRANCH_TO, cause.

       • jenkins  will  do its work and, using webhook, report to pagure that it has finished its
         task

       • pagure will query jenkins to know the outcome of the task and flag the PR accordingly

       REPO corresponds to the url of the repository the pull-request originates  from  (so  most
       often it will be a fork of the main repository).

       BRANCH  corresponds  to  the  branch  the  pull-request originates from (the branch of the
       fork).

       BRANCH_TO corresponds to the targeted branch in the main repository  (the  branch  of  the
       main project in which the PR is to be merged).

       cause is the reason the build was triggered (ie: the pull-request id or the commit hash).

   How to enable Pagure CI
       • Visit the settings page of your project

       • Scroll down to the Hooks section and click on Pagure CI

       • Select the type of CI service you want

       • Enter the URL of the CI service. For example http://jenkins.fedoraproject.org

       • Enter the name of the job the CI service will trigger. For example pagure-ci

       • Tick  the checkbox activating the hook. Either trigger on every commits, trigger only on
         pull-requests or both every commits and pull-requests.

       These steps will activate the hook, after reloading the page or the tab, you will be given
       access to two important values: the token used to trigger the build on jenkins and the URL
       used by jenkins to report the  status  of  the  build.   Keep  these  two  available  when
       configuring jenkins for your project.

   Configure Jenkins
       These steps can only be made by the admins of your jenkins instance, but they only need to
       be made once.

       • Download the following plugins:

         • Git PluginNotification Plugin

   Configure your project on Jenkins
       • Go to the Configure page of your project

       • Under Job Notification  click Add Endpoint

       • Fields in Endpoint will be :

          FORMAT: JSON
          PROTOCOL: HTTP
          EVENT: All Events
          URL: <The URL provided in the Pagure CI hook on pagure>
          TIMEOUT: 3000
          LOG: 1

       • Tick the checkbox This build is parameterized

       • Add two String Parameters named REPO and BRANCH

       • Source Code Management select Git  and give the URL of the pagure project

       • Under Build Trigger click on Trigger build remotely  and  specify  the  token  given  by
         pagure.

       • Under Build -> Add build step -> Execute Shell

       • In the box given  enter the shell steps you want for testing your project.

       Example Script

          # Script specific for Pull-Request build
          if [ -n "$REPO" -a -n "$BRANCH" ]; then
          git remote rm proposed || true
          git remote add proposed "$REPO"
          git fetch proposed
          git checkout origin/master
          git config --global user.email "you@example.com"
          git config --global user.name "Your Name"
          git merge --no-ff "proposed/$BRANCH" -m "Merge PR"
          fi

          # Part of the script specific to how you run the tests on your project

   Tips and tricks
       • How to re-trigger a run of pagure-ci on a pull-request?

       To  manually  trigger  a  run  of  pagure-ci on a given pull-request, simply add a comment
       saying: pretty please pagure-ci rebuild.

       NOTE:
          To always have this handy, you can save it in the Quick Replies!

       NOTE:
          This trigger can also be configured per pagure instance via the configuration file.

   Quick replies
       Quick replies are reusable pieces of text that you can use to start a comment on an  issue
       or  pull  request.  They are meant to remove the hassle of typing a similar response again
       and again.

       Examples where this can be handy:

       • asking for a rebase of a pull request

       • asking a person to add a Signed-off-by line to their commit

       All these requests might be accompanied by a description  on  why  it's  requested.   With
       quick  replies  you  can  prepare the descriptions and the just use them with a click of a
       button.

   Using quick replies
       Any user that can comment will be able to use the quick reply. They are offered in a  drop
       down menu next to the Preview button above comment form.  [image]

       The button is only visible if the project has some quick replies defined.

       Additionally,  the button will become insensitive when you type something into the comment
       box or switch to preview. This should avoid writing over your carefully crafted comment by
       accident. If you remove the text from the field, the button will work again.

   Creating and modifying quick replies
       Project  admins can create them in the settings section. There are no length limits on the
       reply, but only the first 50 characters will be displayed in the menu for users to  choose
       from.  This  limitation  should  encourage  you  to  put the most important message at the
       beginning.

       The order in which you define the replies will be preserved on the chooser menu. This  can
       be used to put the most frequently used ones on the top of the list.

   Troubleshooting
       This  page  lists  some  of  the  potential issues one may have in pagure as well as their
       solution(s).

       Contents:

   Inaccessible pull-requests
   The symptoms
       When trying to open a pull-request, if you run into this error:

          The branch into which this pull-request was to be merged: XXX seems to
          no longer be present in this repo

       (Where XXX is a branch name).

       (Here XXX is m2).

       This means that the pull-request was opened against a branch on your repo  and  that  this
       branch  no  longer  exists.   Pagure  is  therefore unable to compute the diff between the
       sources and the target of the pull-request.

       The pull-request is thus inaccessible but remains in the list of open pull-requests.

   The solution
       The easiest solution to solve this problem is to re-create the target branch in your repo.

       This can be done using git simply by doing:

          git checkout -b <branch_name>
          git push origin <branch_name>

       It will create the branch named <branch_name> in pagure, allowing the diff to be  computed
       for that pull-request and thus allowing it to be displayed. It is then up to you to see if
       this pull-request is still relevant and should be merged or closed.

   Tips and tricks
       This page contains some tips and tricks on how to use pagure. These do not  fit  in  their
       own page but are worth mentioning.

   Place image onto your overview page
       You can only use images that come from the Pagure host itself.

   Example
          ![See Copr workflow](/copr/copr/raw/master/f/doc/img/copr-workflow.png)

       Text in the square brackets will be used as an alt description.

   Pre-fill issue using the URL
       When  creating  issues for a project pagure supports pre-filling the title and description
       input text using URL parameters.

   Example:
       https://pagure.io/pagure/new_issue/?title=<Issue>&content=<Issue Content>

       The above URL will autofill the text boxes for Title and Description field with Title  set
       to <Issue> and Description set to <Issue Content>.

   Pre-fill issue template using the URL
       When  creating  issues for a project pagure supports pre-filling the title and description
       input text using URL parameters.

   Example:
       https://pagure.io/pagure/new_issue/?template=<TemplateName>

       The above URL will autofill the ticket  with  the  specified  template.  The  TemplateName
       should  be the name of the template file on disk (in the templates directory of the ticket
       git repository).

   Filter for issues not having a certain tag
       Very much in the same way pagure allows you to filter for issues  having  a  certain  tag,
       pagure  allows  one  to  filter  for  issues not having a certain tag.  To do this, simply
       prepend a ! in front of the tag.

   Example:
       https://pagure.io/pagure/issues?tags=!easyfix

   Local user creation without email verification
       If you set EMAIL_SEND to `False` from the configuration file,  you  will  get  the  emails
       printed  to  the  console instead of being sent. The admin of the instance can then access
       the URL to  manually  validate  the  account  from  there.  This  is  generally  used  for
       development where we don't need to send any emails.

   Filter an user's projects by their access
       When  watching  a  user's  page,  the  list of all the project that user is involved in is
       presented regardless of whether the user has ticket, commit, admin access or is  the  main
       admin of the project.

       You can specify an acl= argument to the URL to filter the list of projects by access.

       NOTE:
          This also works for your home page when you are logged in.

   Examples:
       https://pagure.io/user/pingou?acl=main    admin    https://pagure.io/user/pingou?acl=admin
       https://pagure.io/user/pingou?acl=commit

   Filter issues by (custom) fields
       Via the project's settings page, admins can set custom keys to be used in issues. You  can
       search  them using the URL via the arguments ckeys and cvalue or simpler, using the search
       field at the top of the issue page.

       This also works for the following regular  fields:  tags,  milestones,  author,  assignee,
       status, priority (but tags and milestones despite their name only support a single value).

   Examples:
       https://pagure.io/SSSD/sssd/issues?status=Open&search_pattern=review%3ATrue
       https://pagure.io/pagure/issues?status=Open&search_pattern=tags%3Aeasyfix

   Search the comments of issues
       One can search all the comments made on an issue tracker using  content:<keyword>  in  the
       search field. This is going to search all the comments (including the descriptions) of all
       the tickets and thus can be quite slow on large project. This is why  this  feature  isn't
       being pushed much forward.

   Examples:
       https://pagure.io/pagure/issues?status=Open&search_pattern=content%3Aeasyfix

   Pagure API
       The  API documentation can be found at https://pagure.io/api/0/ or in /api/0/ of you local
       pagure instance.

INSTALLING PAGURE

       There are two ways to install pagure:

       • via the RPM package (recommended if you are using a RPM-based GNU/Linux distribution)

       • via the setup.py

   Installing pagure via RPM
       Here as well there are two ways of obtaining the RPM:

       • From the main repositories

       Pagure is packaged for Fedora since Fedora 21 and is available for RHEL and its derivative
       via  the  EPEL  repository  <https://fedoraproject.org/wiki/EPEL>.  So installing it is as
       easy as:

          dnf install pagure pagure-milters pagure-ev pagure-webhook

       or

          yum install pagure pagure-milters pagure-ev pagure-webhook

       The pagure package contains the core of the application and  the  doc  server.   (See  the
       Overview page for a global overview of the structure of the project).

       The  pagure-milters  package contains, as the name says, the milter (a mail filter to hook
       into a MTA).

       The pagure-ev package contains the eventsource server.

       The pagure-webhook package contains the web-hook server.

       NOTE:
          The last three packages are optional, pagure would  work  fine  without  them  but  the
          live-update, the webhook and the comment by email services will not work.

       • From the sources

       If  you  wish  to  run  a newer version of pagure than what is in the repositories you can
       easily rebuild it as RPM.

       Simply follow these steps: # Clone the sources:

          git clone https://pagure.io/pagure.git

       # Go to the folder:

          cd pagure

       # Build a tarball of the latest version of pagure:

          python setup.py sdist

       # Build the RPM:

          rpmbuild -ta dist/pagure*.tar.gz

       This will build pagure from the version present in your clone.

       Once, the RPM is installed the services pagure_milter and pagure_ev are ready to  be  used
       but the database and the web-application parts still need to be configured.

   Installing pagure via setup.py
       Pagure  includes  in  its  sources  a  setup.py  automating  the  installation  of the web
       applications of pagure (ie: the core + the doc server).

       To install pagure via this mechanism simply follow these steps: # Clone the sources:

          git clone https://pagure.io/pagure.git

       # Go to the folder:

          cd pagure

       # Install the latest version of pagure:

          python setup.py build
          sudo python setup.py install

       NOTE:
          To  install  the  eventsource  server  or  the  milter,  refer  to   their   respective
          documentations.

       # Install the additional files as follow:

               ┌─────────────────────────────────┬──────────────────────────────────────┐
               │Source                         | │                                      │
               │Destination                      │                                      │
               ├─────────────────────────────────┼──────────────────────────────────────┤
               │files/pagure.cfg.sample        | │                                      │
               │/etc/pagure/pagure.cfg           │                                      │
               ├─────────────────────────────────┼──────────────────────────────────────┤
               │files/alembic.ini/etc/pagure/alembic.ini              │
               ├─────────────────────────────────┼──────────────────────────────────────┤
               │files/pagure.conf/etc/httpd/conf.d/pagure.conf        │
               ├─────────────────────────────────┼──────────────────────────────────────┤
               │files/pagure.wsgi/usr/share/pagure/pagure.wsgi        │
               ├─────────────────────────────────┼──────────────────────────────────────┤
               │createdb.py/usr/share/pagure/pagure_createdb.py │
               └─────────────────────────────────┴──────────────────────────────────────┘

   Set-up pagure
       Once pagure's files are installed, you still need to set up some things.

       • Create the folder release

       This folder is used by project maintainers to upload the tarball of the releases of  their
       project.

       This  folder must be accessible by the user under which the application is running (in our
       case: git).

          mkdir -p /var/www/releases
          chown git:git /var/www/releases

       • Create the folders where the repos, forks and checkouts will be stored

       Pagure stores the sources of a project in  a  git  repo,  offers  a  place  to  store  the
       project's  documentation  in  another  repo,  stores  a JSON dump of all issues and of all
       pull-requests in another two repos, and keeps a local checkout  of  remote  projects  when
       asked  to do remote pull-requests.  All these repositories are stored in different folders
       that must be created manually.

       For example you can place them under /srv/git/repositories/ which would make /srv/git  the
       home of your gitolite user.

       You would then create the folders with:

          mkdir /srv/git/repositories/{docs,forks,tickets,requests,remotes}

       • Configure apache

       If   installed   by   RPM,  you  will  find  an  example  apache  configuration  file  at:
       /etc/httpd/conf.d/pagure.conf.

       If not installed by RPM, the example file is present in the sources at: files/pagure.conf.

       Adjust it for your needs.

       • Configure the WSGI file

       If   you   installed   by   RPM,    you    will    find    example    WSGI    files    at:
       /usr/share/pagure/pagure.wsgi  for  the  core server and /usr/share/pagure/doc_pagure.wsgi
       for the doc server.

       If  you  did  not  install  by  RPM,  these  files  are  present  in   the   sources   at:
       files/pagure.wsgi and files/doc_pagure.wsgi.

       Adjust them for your needs

       • Give apache permission to read the repositories owned by the git user.

       For the sake of this document, we assume that the web application runs under the git user,
       the same user as your gitolite user, but apache itself runs under the httpd  (or  apache2)
       user.  So  by  default,  apache  will  not be allowed to read git repositories created and
       managed by gitolite.

       To give apache this permission (required to make git clone via http  work),  we  use  file
       access control lists (aka FACL):

          setfacl -m user:apache:rx --default
          setfacl -Rdm user:apache:rx /srv/git
          setfacl -Rm user:apache:rx /srv/git

       Where  /srv/git is the home of your gitolite user (which will thus need to be adjusted for
       your configuration).

       • Set up the configuration file of pagure

       This is an important step which concerns the file  /etc/pagure/pagure.cfg.   If  you  have
       installed pagure by RPM, this file is already there, otherwise you can find an example one
       in the sources at: files/pagure.cfg.sample that  you  will  have  to  copy  to  the  right
       location.

       Confer  the  Configuration section of this documentation for a full explanation of all the
       options of pagure.

       • Create the database

       You first need to create the database itself.  For  this,  since  pagure  can  work  with:
       PostgreSQL,  MySQL or MariaDB, we would like to invite you to consult the documentation of
       your database system for this operation.

       Once you have specified in the configuration file the  to  url  used  to  connect  to  the
       database,  and  create  the  database  itself, you can now create the tables, the database
       scheme.

       For changes to existing tables, we rely on Alembic.  It  uses  revisions  to  perform  the
       upgrades,  but  to  know which upgrades are needed and which are already done, the current
       revision needs to be saved in the database. This will allow alembic to know and apply  the
       new revision when running it.

       In  the  alembic.ini file, one of the configuration key is most important: script_location
       which is the path to the versions folder containing all the alembic migration  files.  The
       sqlalchemy.url  configuration  key  if  missing  will be replaced by the url filled in the
       configuration file of pagure.

       To    create    the    database    tables,    you    need    to     run     the     script
       /usr/share/pagure/pagure_createdb.py  and  specify the configuration to use for pagure and
       for alembic.

       For example:

          python /usr/share/pagure/pagure_createdb.py -c /etc/pagure/pagure.cfg -i /etc/pagure/alembic.ini

       This will  tell  /usr/share/pagure/pagure_createdb.py  to  use  the  database  information
       specified in the file /etc/pagure/pagure.cfg and to stamp the database at the last alembic
       revision.

       WARNING:
          Pagure's default configuration is using sqlite. This is fine  for  development  purpose
          but  not  for  production use as sqlite does not support all the operations needed when
          updating the database schema. Do use PostgreSQL, MySQL or MariaDB in production.

       For changes to existing tables, we rely on Alembic.  It  uses  revisions  to  perform  the
       upgrades,  but  to  know which upgrades are needed and which are already done, the current
       revision needs to be saved in the database. This will allow alembic to know apply the  new
       revision when running it.

       In  the  alembic.ini file, one of the configuration key is most important: script_location
       which is the path to the versions folder containing all the alembic migration  files.  The
       sqlalchemy.url  configuration  key  if  missing  will be replaced by the url filled in the
       configuration file of pagure.

       WARNING:
          Calling pagure_createdb.py is  asked  regularly  in  the  UPGRADING.rst  documentation,
          especially  to handle database schema changes upon upgrades, but the --initial argument
          should only be used the first time as it will otherwise break  upgrading  the  database
          schema via alembic.

       NOTE:
          When install from source the script is called createdb.py and not pagure_createdb.py.

       If you installed by RPM, then enable and start the worker services

          systemctl enable --now pagure_worker.service pagure_gitolite_worker.service

   Set up virus scanning
       Pagure  can  automatically  scan uploaded attachments for viruses using Clam.  To set this
       up,   first   install   clamav-data-empty,   clamav-server,   clamav-server-systemd    and
       clamav-update.

       Then  edit /etc/freshclam.conf, removing the Example line and run freshclam once to get an
       up to date database.

       Copy /usr/share/doc/clamav-server/clamd.conf to /etc/clamd.conf and edit that  too,  again
       making  sure  to  remove  the  Example  line.  Make sure to set LocalSocket to a file in a
       directory that exists, and set User to an existing system user.

       Then start the  clamd  service  and  set  VIRUS_SCAN_ATTACHMENTS  =  True  in  the  Pagure
       configuration.

INSTALLING PAGURE'S MILTER

       A  milter  is  a script that is ran by a Mail Transfer Agent (MTA) upon receiving an email
       via either a network or an unix socket.

       If you want more information feel free to check out the corresponding page  on  wikipedia:
       https://en.wikipedia.org/wiki/Milter.

   Configure your system
       • Install the required dependencies

          python-pymilter

       NOTE:
          We  ship  a  systemd unit file for pagure_milter but we welcome patches for scripts for
          other init systems.

       NOTE:
          It also requires a MTA, we used postfix.

       • Create an alias reply

       This can be done in /etc/aliases, for example:

          reply:      /dev/null

       • Activate the ability of your MTA, to split users based on the character +.  This way all
         the emails sent to reply+...@example.com will be forwarded to your alias for reply.

       In postfix this is done via:

          recipient_delimiter = +

       • Hook the milter in the MTA

       In postfix this is done via:

          non_smtpd_milters = unix:/var/run/pagure/paguresock
          smtpd_milters = unix:/var/run/pagure/paguresock

       • Install the files of the milter as follow:

          ┌───────────────────────────────────────┬───────────────────────────────────────────┐
          │Source                                 │ Destination                               │
          ├───────────────────────────────────────┼───────────────────────────────────────────┤
          │pagure-milters/comment_email_milter.py/usr/share/pagure/comment_email_milter.py │
          ├───────────────────────────────────────┼───────────────────────────────────────────┤
          │pagure-milters/milter_tempfile.conf/usr/lib/tmpfiles.d/pagure-milter.conf    │
          ├───────────────────────────────────────┼───────────────────────────────────────────┤
          │pagure-milters/pagure_milter.service/etc/systemd/system/pagure_milter.service │
          └───────────────────────────────────────┴───────────────────────────────────────────┘

       The first file is the script of the milter itself.

       The  second  file is a file specific for systemd and ensuring the temporary folders needed
       by the milter are re-created if needed at each boot.

       The third file is the systemd service file.

       • Activate the service and ensure it's started upon boot:

          systemctl enable pagure_milter
          systemctl start pagure_milter

INSTALLING PAGURE'S EVENTSOURCE SERVER

       Eventsource or Server Sent Events are messages sent from a server to  a  web  browser.  It
       allows one to refresh a page "live", ie, without the need to reload it entirely.

   Configure your system
       The eventsource server is easy to set-up.

       • Install the required dependencies

          python-redis
          python-trololio

       NOTE:
          We  ship  a  systemd unit file for pagure_milter but we welcome patches for scripts for
          other init systems.

       • Install the files of the SSE server as follow:

          ┌──────────────────────────────────┬────────────────────────────────────────────────┐
          │Source                            │ Destination                                    │
          ├──────────────────────────────────┼────────────────────────────────────────────────┤
          │pagure-ev/pagure_stream_server.py/usr/libexec/pagure-ev/pagure_stream_server.py │
          ├──────────────────────────────────┼────────────────────────────────────────────────┤
          │pagure-ev/pagure_ev.service/etc/systemd/system/pagure_ev.service          │
          └──────────────────────────────────┴────────────────────────────────────────────────┘

       The first file is the script of the SSE server itself.

       The second file is the systemd service file.

       • Finally, activate the service and ensure it's started upon boot:

          systemctl enable redis
          systemctl start redis
          systemctl enable pagure_ev
          systemctl start pagure_ev

INSTALLING PAGURE'S WEB-HOOKS NOTIFICATION SYSTEM

       Web-hooks are a notification system upon which a system makes a  http  POST  request  with
       some  data  upon  doing  an  action.  This  allows  notifying  a system that an action has
       occurred.

       If you want more information feel free to check out the corresponding page  on  wikipedia:
       https://en.wikipedia.org/wiki/Webhook.

   Configure your system
       • Install the required dependencies

          python-redis
          python-trololio

       NOTE:
          We  ship  a systemd unit file for pagure_webhook but we welcome patches for scripts for
          other init systems.

       • Install the files of the web-hook server as follow:

    ┌────────────────────────────────────────┬──────────────────────────────────────────────────────┐
    │Source                                  │ Destination                                          │
    ├────────────────────────────────────────┼──────────────────────────────────────────────────────┤
    │pagure-webhook/pagure-webhook-server.py/usr/libexec/pagure-webhook/pagure-webhook-server.py │
    ├────────────────────────────────────────┼──────────────────────────────────────────────────────┤
    │pagure-webhook/pagure_webhook.service/etc/systemd/system/pagure_webhook.service           │
    └────────────────────────────────────────┴──────────────────────────────────────────────────────┘

       The first file is the script of the web-hook server itself.

       The second file is the systemd service file.

       • Activate the service and ensure it's started upon boot:

          systemctl enable redis
          systemctl start redis
          systemctl enable pagure_webhook
          systemctl start pagure_webhook

INSTALLING PAGURE-CI

       A CI stands for Continuous Integration. Pagure can  be  configured  to  integrate  results
       coming from CI services, such as Jenkins on pull-request opened against the project.

   Configure your system
       • Install the required dependencies

          python-jenkins
          python-redis
          python-trololio

       NOTE:
          We  ship a systemd unit file for pagure_ci but we welcome patches for scripts for other
          init systems.

       • Install the files of pagure-ci as follow:

              ┌──────────────────────────────┬────────────────────────────────────────────┐
              │Source                        │ Destination                                │
              ├──────────────────────────────┼────────────────────────────────────────────┤
              │pagure-ci/pagure_ci_server.py/usr/libexec/pagure-ci/pagure_ci_server.py │
              ├──────────────────────────────┼────────────────────────────────────────────┤
              │pagure-ci/pagure_ci.service/etc/systemd/system/pagure_ci.service      │
              └──────────────────────────────┴────────────────────────────────────────────┘

       The  first  file  is  the pagure-ci service itself, triggering the build on the CI service
       when there is a new pull-request or a change to an existing one.

       The second file is the systemd service file.

       • Configure your pagure instance to support CI, add the following  to  your  configuration
         file

          PAGURE_CI_SERVICES = ['jenkins']

       • Activate the service and ensure it's started upon boot:

          systemctl enable redis
          systemctl start redis
          systemctl enable pagure_ci
          systemctl start pagure_ci

INSTALLING PAGURE-LOADJSON

       pagure-loadjson  is the service that updates the database based on the content of the JSON
       blob pushed into the ticket git repository (and in the future for pull-requests as well).

   Configure your system
       • Install the required dependencies

          python-redis
          python-trololio

       NOTE:
          We ship a systemd unit file for pagure_loadjson but we welcome patches for scripts  for
          other init systems.

       • Install the files of pagure-loadjon as follow:

      ┌──────────────────────────────────────────┬─────────────────────────────────────────────────┐
      │Source                                    │ Destination                                     │
      ├──────────────────────────────────────────┼─────────────────────────────────────────────────┤
      │pagure-loadjson/pagure_loadjson_server.py/usr/libexec/pagure-loadjson/pagure_loadjson.py │
      ├──────────────────────────────────────────┼─────────────────────────────────────────────────┤
      │pagure-loadjson/pagure_loadjson.service/etc/systemd/system/pagure_loadjson.service     │
      └──────────────────────────────────────────┴─────────────────────────────────────────────────┘

       The  first  file is the pagure-loadjson service itself, triggered by the git hook (shipped
       with pagure itself) and loading the JSON files into the database.

       The second file is the systemd service file.

       • Activate the service and ensure it's started upon boot:

          systemctl enable redis
          systemctl start redis
          systemctl enable pagure_loadjson
          systemctl start pagure_loadjson

INSTALLING PAGURE-LOGCOM

       pagure-logcom is the service that updates the log table in the database for  every  commit
       made  to  the main branch of a repository allowing to build the calendar heatmap presented
       on every user's page.

   Configure your system
       • Install the required dependencies

          python-redis
          python-trololio

       NOTE:
          We ship a systemd unit file for pagure_logcom but we welcome patches  for  scripts  for
          other init systems.

       • Install the files of pagure-loadjon as follow:

                   ┌───────────────────────────────────────────────────┬─────────────┐
                   │Source                                             │ Destination │
                   ├───────────────────────────────────────────────────┼─────────────┤
                   │pagure-logcom/pagure_logcom_server.py              │             │
                   │|                                                  │             │
                   │/usr/libexec/pagure-logcom/pagure_logcom_server.py │             │
                   ├───────────────────────────────────────────────────┼─────────────┤
                   │pagure-logcom/pagure_logcom.service              | │             │
                   │/etc/systemd/system/pagure_logcom.service          │             │
                   └───────────────────────────────────────────────────┴─────────────┘

       The  first  file  is  the pagure-logcom service itself, triggered by the git hook (shipped
       with pagure itself) and logging the commits into the database.

       The second file is the systemd service file.

       • Activate the service and ensure it's started upon boot:

          systemctl enable redis
          systemctl start redis
          systemctl enable pagure_logcom
          systemctl start pagure_logcom

CRON JOBS

       Some actions in pagure are meant to the run via a cron job.

   API key expiration reminder
       One of the cron job sending reminder about API keys that are about  to  expire.   It  will
       send  an  email  10  days,  then  5 days and finally the day before the key expires to the
       person who has created.

       The cron job can be found in the sources in:

          files/api_key_expire_mail.py

       In the RPM it is installed in:

          /usr/share/pagure/api_key_expire_mail.py

       This cron job is meant to be run daily using a syntax similar to:

          10 0 * * * root python /usr/share/pagure/api_key_expire_mail.py

       which will make the script run at 00:10 every day.

CONFIGURATION

       Pagure offers a wide varieties of options that must or can be used to adjust its behavior.

       All of these options can be edited or added to  your  configuration  file.   If  you  have
       installed  pagure,  this  configuration  file is likely located in /etc/pagure/pagure.cfg.
       Otherwise, it will depend on your setup/deployment.

   Must options
       Here are the options you must set up in order to get pagure running.

   SECRET_KEY
       This configuration key is used by flask to create the session. It should  be  kept  secret
       and set as a long and random string.

   SALT_EMAIL
       This  configuration  key  is  used  to ensure that when sending notifications to different
       users, each one of them has a different,  unique  and  unfakeable  Reply-To  header.  This
       header  is then used by the milter to find out if the response received is a real one or a
       fake/invalid one.

   DB_URL
       This configuration key indicates to the framework how and where to connect to the database
       server.  Pagure  uses  SQLAchemy  to  connect to a wide range of database server including
       MySQL, PostgreSQL, and SQLite.

       Examples values:

          DB_URL = 'mysql://user:pass@host/db_name'
          DB_URL = 'postgres://user:pass@host/db_name'
          DB_URL = 'sqlite:////var/tmp/pagure_dev.sqlite'

       Defaults to sqlite:////var/tmp/pagure_dev.sqlite

   APP_URL
       This configuration key indicates the URL at  which  this  pagure  instance  will  be  made
       available.

       Defaults to: http://localhost.localdomain/

   EMAIL_ERROR
       Pagure  sends  email  when  it catches an unexpected error (which saves you from having to
       monitor the logs regularly; but if you like, the error is  still  present  in  the  logs).
       This  configuration  key  allows you to specify to which email address to send these error
       reports.

   GIT_URL_SSH
       This configuration key provides the information to the user on how to clone the git  repos
       hosted on pagure via SSH.

       The URL should end with a slash /.

       Defaults to: 'ssh://git@llocalhost.localdomain/'

       NOTE:
          If  you are using a custom setup for your deployment where every user has an account on
          the machine you may want to tweak this URL to include the  username.  If  that  is  the
          case,  you can use {username} in the URL and it will be expanded to the username of the
          user viewing the page when rendered.  For example: 'ssh://{username}@pagure.org/'

   GIT_URL_GIT
       This configuration key provides the information to the user on how to clone the git  repos
       hosted  on  pagure  anonymously.  This  access can be granted via the git:// or http(s)://
       protocols.

       The URL should end with a slash /.

       Defaults to: 'git://localhost.localdomain/'

   BROKER_URL
       This configuration key is used to point celery to the broker to use. This  is  the  broker
       that is used to communicate between the web application and its workers.

       Defaults to: 'redis://%s' % APP.config['REDIS_HOST']

       NOTE:
          See the Redis options for the REDIS_HOST configuration key

   Repo Directories
       Each  project  in  pagure  has  2 to 4 git repositories, depending on configuration of the
       Pagure instance (see below):

       • the main repo for the code

       • the doc repo showed in the doc server (optional)

       • the ticket repo storing the metadata of the tickets (optional)

       • the request repo storing the metadata of the pull-requests

       There are then another 3 folders: one for specifying the locations of the forks,  one  for
       the  remote  git  repo used for the remotes pull-requests (ie: those coming from a project
       not hosted on this instance of pagure), and one for user-uploaded tarballs.

   GIT_FOLDER
       This configuration key points to the folder where the git repos  are  stored.   For  every
       project, two to four repos are created:

       • a repo with source code of the project

       • a repo with documentation of the project (if ENABLE_DOCS is True)

       • a repo with metadata of tickets opened against the project (if ENABLE_TICKETS is True)

       • a repo with metadata of pull requests opened against the project

       Note that gitolite config value GL_REPO_BASE (if using gitolite 3) or $REPO_BASE (if using
       gitolite 2) must have exactly the same value as GIT_FOLDER.

   REMOTE_GIT_FOLDER
       This configuration key points to the folder where the remote git repos (ie: not hosted  on
       pagure)  that  someone  used to open a pull-request against a project hosted on pagure are
       stored.

   UPLOAD_FOLDER_PATH
       This configuration key points to the folder where user-uploaded tarballs  are  stored  and
       served from.

   ATTACHMENTS_FOLDER
       This  configuration  key  points  to the folder where attachments can be cached for easier
       access by the web-server (allowing to not interact with the git repo having  it  to  serve
       it).

   UPLOAD_FOLDER_URL
       Full URL to where the uploads are available. It is highly recommended for security reasons
       that this URL lives on a different domain than the main application (an entirely different
       domain, not just a sub-domain).

       Defaults to: /releases/, unsafe for production!

       WARNING:
          both  UPLOAD_FOLDER_PATH and UPLOAD_FOLDER_URL must be specified for the upload release
          feature to work

   SESSION_COOKIE_SECURE
       When this is set to True, the session cookie will only be returned to the server  via  ssl
       (https).  If  you  connect to the server via plain http, the cookie will not be sent. This
       prevents sniffing of the cookie contents.  This may be set  to  False  when  testing  your
       application but should always be set to True in production.

       Defaults to: False for development, must be True in production with https.

   SESSION_TYPE
       Enables  the  flask-session extension if set to a value other than None. The flask-session
       package needs to be installed and proper configuration needs to be included in the  Pagure
       config file.

       This  is  useful when the Pagure server needs to be scaled up to multiple instances, which
       requires the flask session keys to be shared between those.  Flask-session allows  you  to
       use Redis, Memcached, relational database or MongoDB for storing shared session keys.

   FROM_EMAIL
       This  configuration  key  specifies  the  email  address used by this pagure instance when
       sending emails (notifications).

       Defaults to: pagure@localhost.localdomain

   DOMAIN_EMAIL_NOTIFICATIONS
       This configuration key specifies the domain used by  this  pagure  instance  when  sending
       emails  (notifications). More precisely, it is used when building the msg-id header of the
       emails sent.

       Defaults to: localhost.localdomain

   VIRUS_SCAN_ATTACHMENTS
       This configuration key configures whether attachments are scanned for viruses  on  upload.
       For more information, see the install.rst guide.

       Defaults to: False

   GIT_AUTH_BACKEND
       This configuration key allows specifying which git auth backend to use.

       Git  auth  backends  can  either be static (like gitolite), where a file is generated when
       something changed and then used on login, or dynamic, where the actual ACLs are checked in
       a git hook before being applied.

       By default pagure provides the following backends:

       • test_auth:   simple   debugging   backend  printing  and  returning  the  string  Called
         GitAuthTestHelper.generate_acls()gitolite2: allows deploying pagure on the top of gitolite 2

       • gitolite3: allows deploying pagure on the top of gitolite 3

       • pagure: Pagure git auth implementation (using keyhelper.py and  aclchecker.py)  that  is
         used via sshd AuthorizedKeysCommand

       • pagure_authorized_keys:  Pagure  git  auth implementation that writes to authorized_keys
         file

       Defaults to: gitolite3

       NOTE:
          The option GITOLITE_BACKEND is the legacy name, and for backwards compatibility reasons
          will override this setting

       NOTE:
          These options can be expended, cf Customize the gitolite configuration.

   Configure Pagure Auth
       Pagure  offers  a  simple,  but  extensible  internal  authentication  mechanism  for  Git
       repositories. It relies on SSH for authentication. In other words, SSH  lets  you  in  and
       Pagure checks if you are allowed to do what you are trying to do once you are inside.

       This  authentication  mechanism  uses  keyhelper.py  and aclchecker.py to check the Pagure
       database for user registered SSH keys to do the authentication.

       The integrated authentication mechanism has two  modes  of  operation:  one  where  it  is
       configured  as  the AuthorizedKeysCommand for the SSH user (preferred) and one where it is
       configured to manage the authorized_keys file for the SSH user.

       In the preferred mode, when you attempt to do an action with a remote Git  repo  over  SSH
       (e.g.  git  clone ssh://git@localhost.localdomain/repository.git), the SSH server will ask
       Pagure to validate the SSH user key. This has the advantage of performance (no  racey  and
       slow  file  I/O) but has the disadvantage of requiring changes to the system's sshd_config
       file to use it.

       To use this variant, set the following in pagure.cfg:

          GIT_AUTH_BACKEND = "pagure"

          HTTP_REPO_ACCESS_GITOLITE = None

          SSH_KEYS_USERNAME_EXPECT = "git"

          SSH_COMMAND_NON_REPOSPANNER = ([
              "/usr/bin/%(cmd)s",
              "/srv/git/repositories/%(reponame)s",
          ], {"GL_USER": "%(username)s"})

       Setting the following in /etc/ssh/sshd_config is also required:

          Match User git
              AuthorizedKeysCommand /usr/libexec/pagure/keyhelper.py "%u" "%h" "%t" "%f"
              AuthorizedKeysCommandUser git

       If you do not have the ability to modify the sshd  configuration  to  set  up  the  pagure
       backend, then you need to use the pagure_authorized_keys alternative backend. This backend
       will write to the git user's  authorized_keys  file  instead.  This  is  slower  than  the
       preferred  mode and also has the disadvantage of making it impossible to scale to multiple
       Pagure frontend instances on top of  a  shared  Git  storage  without  causing  races  and
       triggering  inconsistencies.  It also adds to the I/O contention on a heavily used system,
       but for most smaller setups with few users, the trade-off is not noticeable.

       To use  this  variant,  enable  the  pagure_authorized_keys_worker  service  and  set  the
       following to pagure.cfg:

          SSH_FOLDER = "/srv/git/.ssh"

          GIT_AUTH_BACKEND = "pagure_authorized_keys"

          HTTP_REPO_ACCESS_GITOLITE = None

          SSH_COMMAND_NON_REPOSPANNER = ([
              "/usr/bin/%(cmd)s",
              "/srv/git/repositories/%(reponame)s",
          ], {"GL_USER": "%(username)s"})

   Configure Gitolite
       Pagure  can  use  gitolite  as  an  authorization  layer.   Gitolite relies on SSH for the
       authentication. In other words, SSH lets you in and gitolite checks if you are allowed  to
       do what you are trying to do once you are inside.

       Pagure  supports  both  gitolite  2  and  gitolite  3 and the code generating the gitolite
       configuration can be customized for easier integration with other  systems  (cf  Customize
       the gitolite configuration).

       Using Gitolite also requires setting the following in pagure.cfg:

          HTTP_REPO_ACCESS_GITOLITE = "/usr/share/gitolite3/gitolite-shell"

          SSH_COMMAND_NON_REPOSPANNER = (
              [
                  "/usr/share/gitolite3/gitolite-shell",
                  "%(username)s",
                  "%(cmd)s",
                  "%(reponame)s",
              ],
              {},
          )

       This  ensures that the Gitolite environment is used for interacting with Git repositories.
       Further customizations are listed below.

   gitolite 2 and 3
   GITOLITE_HOME
       This configuration key points to the home directory of the user under  which  gitolite  is
       ran.

   GITOLITE_KEYDIR
       This  configuration key points to the folder where gitolite stores and accesses the public
       SSH keys of all the user have access to the server.

       Since pagure is the user interface, it is pagure  that  writes  down  the  files  in  this
       directory, effectively setting up the users to be able to use gitolite.

   GITOLITE_CONFIG
       This  configuration  key points to the gitolite.conf file where pagure writes the gitolite
       repository access configuration.

   GITOLITE_CELERY_QUEUE
       This configuration is useful for large pagure deployment where  recompiling  the  gitolite
       config  file  can take a long time. By default the compilation of gitolite's configuration
       file is done by the pagure_worker, which spawns by default 4  concurrent  workers.  If  it
       takes  a while to recompile the gitolite configuration file, these workers may be stepping
       on each others' toes.  In this situation, this configuration key allows you to direct  the
       messages  asking  for  the gitolite configuration file to be compiled to a different queue
       which can then be handled by a different service/worker.

       Pagure provides a pagure_gitolite_worker.service systemd service  file  pre-configured  to
       handles these messages if this configuration key is set to gitolite_queue.

   gitolite 2 only
   GL_RC
       This  configuration  key points to the file gitolite.rc used by gitolite to record who has
       access to what (ie: who has access to which repo/branch).

   GL_BINDIR
       This configuration key indicates the folder in which the gitolite tools can be  found.  It
       can  be as simple as /usr/bin/ if the tools have been installed using a package manager or
       something like /opt/bin/ for a more custom install.

   gitolite 3 only
   GITOLITE_HAS_COMPILE_1
       By setting this configuration key to True, you can turn on using  the  gitolite  compile-1
       binary. This speeds up gitolite task when it recompiles configuration after new project is
       created. In order to use this, you need to have the compile-1 gitolite command.

       There are two ways to have it,

       1. You distribution already has the file installed for you and you can then just use it.

       2. You need to download and install it yourself. We are describing what needs to  be  done
          for this here below.

       Installing the compile-1 command:

       • You also have to make sure that your distribution of gitolite contains patch which makes
         gitolite respect  ALLOW_ORPHAN_GL_CONF  configuration  variable,  if  this  patch  isn't
         already present, you will have to make the change yourself.

       • In your gitolite.rc set ALLOW_ORPHAN_GL_CONF to 1 (you may have to add it yourself).

       • Still in your gitolite.rc file, uncomment LOCAL_CODE file and set it to a full path of a
         directory that you choose (for example /usr/local/share/gitolite3).

       • Create a subdirectory commands under the path you picked for LOCAL_CODE (in our example,
         you will need to do: mkdir -p /usr/local/share/gitolite3/commands)

       • Finally,   install   the  compile-1  command  in  this  commands  subdirectory  If  your
         installation doesn't ship  this  file,  you  can  download  it.   (Ensure  the  file  is
         executable, otherwise gitolite will not find it)

       Defaults to: False

   EventSource options
   EVENTSOURCE_SOURCE
       This  configuration key indicates the URL at which the EventSource server is available. If
       not defined, pagure will behave as if there are no EventSource server running.

   EVENTSOURCE_PORT
       This configuration key indicates the port at which the EventSource server is running.

       NOTE:
          The EventSource server requires a redis server (see Redis options below)

   Web-hooks notifications
   WEBHOOK
       This configuration key allows turning on or off web-hooks notifications  for  this  pagure
       instance.

       Defaults to: False.

       NOTE:
          The Web-hooks server requires a redis server (see Redis options below)

   Redis options
   REDIS_HOST
       This configuration key indicates the host at which the redis server is running.

       Defaults to: 0.0.0.0.

   REDIS_PORT
       This configuration key indicates the port at which the redis server can be contacted.

       Defaults to: 6379.

   REDIS_DB
       This  configuration  key indicates the name of the redis database to use for communicating
       with the EventSource server.

       Defaults to: 0.

   Authentication options
   ADMIN_GROUP
       List of groups, either local or remote (if the  openid  server  used  supports  the  group
       extension),   that  are  the  site  admins.  These  admins  can  regenerate  the  gitolite
       configuration, the ssh key files, and the hook-token for every project as well  as  manage
       users and groups.

   PAGURE_ADMIN_USERS
       List  of  local  users  that are the site admins. These admins have the same rights as the
       users in the admin groups listed above as well as admin rights to all projects  hosted  on
       this pagure instance.

   Celery Queue options
       In  order  to  help prioritize between tasks having a direct impact on the user experience
       and tasks needed to be run on the background but not directly impacting the users, we have
       split the generic tasks triggered by the web application into three possible queues: Fast,
       Medium, Slow.  If none of these options are set, a single  queue  will  be  used  for  all
       tasks.

   FAST_CELERY_QUEUE
       This  configuration  key  can  be  used  to  specify  a dedicated queue for tasks that are
       triggered by the web frontend  and  need  to  be  processed  quickly  for  the  best  user
       experience.

       This  will  be  used  for  tasks  such  as  creating  a  new project, forking or merging a
       pull-request.

       Defaults to: None.

   MEDIUM_CELERY_QUEUE
       This configuration key can be used to  specify  a  dedicated  queue  for  tasks  that  are
       triggered  by  the  web frontend and need to be processed but aren't critical for the best
       user experience.

       This will be used for tasks such as updating a file in a git repository.

       Defaults to: None.

   SLOW_CELERY_QUEUE
       This configuration key can be used to  specify  a  dedicated  queue  for  tasks  that  are
       triggered  by the web frontend, are slow and do not impact the user experience in the user
       interface.

       This will be used for tasks such as updating the ticket git  repo  based  on  the  content
       posted in the user interface.

       Defaults to: None.

   Stomp Options
       Pagure  integration  with Stomp allows you to emit messages to any stomp-compliant message
       bus.

   STOMP_NOTIFICATIONS
       This configuration key can be used to turn on or off notifications via stomp protocol. All
       other stomp-related settings don't need to be present if this is set to False.

       Defaults to: False.

   STOMP_BROKERS
       List  of 2-tuples with broker domain names and ports. For example [('primary.msg.bus.com',
       6543), ('backup.msg.bus.com`, 6543)].

   STOMP_HIERARCHY
       Base name of the hierarchy to emit messages to. For example  /queue/some.hierarchy..  Note
       that  this must end with a dot. Pagure will append queue names such as project.new to this
       value, resulting in queue names being e.g.  /queue/some.hierarchy.project.new.

   STOMP_SSL
       Whether or not to use SSL when connecting to message brokers.

       Defaults to: False.

   STOMP_KEY_FILE
       Absolute path to key file for SSL connection. Only required if STOMP_SSL is set to True.

   STOMP_CERT_FILE
       Absolute path to certificate file for SSL connection. Only required if STOMP_SSL is set to
       True.

   STOMP_CREDS_PASSWORD
       Password  for  decoding  STOMP_CERT_FILE and STOMP_KEY_FILE. Only required if STOMP_SSL is
       set to True and credentials files are password-encoded.

   ALWAYS_STOMP_ON_COMMITS
       This configuration key can be used to enforce stomp notifications on commits made  on  all
       projects in a pagure instance.

       Defaults to: False.

   API token ACLs
   ACLS
       This  configuration key lists all the ACLs that can be associated with an API token with a
       short description of what the ACL allows one to do.  This key it not really  meant  to  be
       changed unless you really know what you are doing.

   USER_ACLS
       This  configuration  key  can  be  used  to  list  which of the ACLs listed in ACLS can be
       associated with an API token of a project in the (web) user interface.

       Use this configuration key in combination with ADMIN_API_ACLS to disable certain ACLs  for
       users while allowing admins to generate keys with them.

       Defaults to: [key for key in ACLS.keys() if key != 'generate_acls_project']
              (ie: all the ACLs in ACLS except for generate_acls_project)

   ADMIN_API_ACLS
       This  configuration  key  can  be  used  to  list  which of the ACLs listed in ACLS can be
       generated by the pagure-admin CLI tool by admins.

       Defaults to: ['issue_comment', 'issue_create', 'issue_change_status', 'pull_request_flag',
       'pull_request_comment',   'pull_request_merge',   'generate_acls_project',  'commit_flag',
       'create_branch']

   CROSS_PROJECT_ACLS
       This configuration key can be used to list which  of  the  ACLs  listed  in  ACLS  can  be
       associated  with a project-less API token in the (web) user interface.  These project-less
       API tokens can be generated in the user's settings page  and  allows  action  in  multiple
       projects instead of being restricted to a specific one.

       Defaults to: ['create_project', 'fork_project', 'modify_project']

   Optional options
   Theming
   THEME
       This configuration key allows you to specify the theme to be used. The string specified is
       the name of the theme directory in pagure/themes/

       For more information about theming see the Theming Guide

       Default options:

       • chameleon  The OpenSUSE theme for pagure

       • default  The default theme for pagure

       • pagureio  The theme used at https://pagure.iosrcfpo  The theme used at https://src.fedoraproject.org

       Defaults to: default

   Git repository templates
   PROJECT_TEMPLATE_PATH
       This configuration key allows you to specify the path to a git  repository  to  use  as  a
       template  when  creating  new repository for new projects.  This template will not be used
       for forks nor any of the git repository but the one used for the sources (ie: it will  not
       be used for the tickets, requests or docs repositories).

   FORK_TEMPLATE_PATH
       This  configuration  key  allows  you  to specify the path to a git repository to use as a
       template when creating new repository for new forks.  This template will not be  used  for
       any  of  the  git repository but the one used for the sources of forks (ie: it will not be
       used for the tickets, requests or docs repositories).

   SSH_KEYS
       It is a good practice to publish the fingerprint and  public  SSH  key  of  a  server  you
       provide  access to.  Pagure offers the possibility to expose this information based on the
       values set in the configuration file, in the SSH_KEYS configuration key.

       See the SSH hostkeys/Fingerprints page on pagure.io.

       Where <foo> and <bar> must be replaced by your values.

   CSP_HEADERS
       Content Security Policy (CSP) is  a  computer  security  standard  introduced  to  prevent
       cross-site  scripting  (XSS), clickjacking and other code injection attacks resulting from
       execution of malicious content in the trusted web page context

       Source: https://en.wikipedia.org/wiki/Content_Security_Policy

       Defaults to:

          CSP_HEADERS = (
              "default-src 'self' https:; "
              "script-src 'self' 'nonce-{nonce}'; "
              "style-src 'self' 'nonce-{nonce}'"
          )

       Where {nonce} is dynamically set by pagure.

   LOGGING_GIT_HOOKS
       This configuration key allows to have  a  different  logging  configuration  for  the  web
       application and the git hooks.

       If  un-specified  (default),  the  logging configuration used by the git hooks will be the
       same as the one for the web application (i.e.: defined in LOGGING here below).

       Defaults to: None.

   LOGGING
       This configuration key allows you to set up the logging of the application.  It relies  on
       the standard python logging module.

       The default value is:

          LOGGING = {
               "version": 1,
               "disable_existing_loggers": False,
               "formatters": {
                   "standard": {
                       "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
                   },
                   "email_format": {"format": MSG_FORMAT},
               },
               "filters": {"myfilter": {"()": ContextInjector}},
               "handlers": {
                   "console": {
                       "formatter": "standard",
                       "class": "logging.StreamHandler",
                       "stream": "ext://sys.stdout",
                   },
                   "auth_handler": {
                       "formatter": "standard",
                       "class": "logging.StreamHandler",
                       "stream": "ext://sys.stdout",
                   },
                   "email": {
                       "level": "ERROR",
                       "formatter": "email_format",
                       "class": "logging.handlers.SMTPHandler",
                       "mailhost": "localhost",
                       "fromaddr": "pagure@localhost",
                       "toaddrs": "root@localhost",
                       "subject": "ERROR on pagure",
                       "filters": ["myfilter"],
                   },
               },
               # The root logger configuration; this is a catch-all configuration
               # that applies to all log messages not handled by a different logger
               "root": {"level": "INFO", "handlers": ["console"]},
               "loggers": {
                   "pagure": {
                       "handlers": ["console"],
                       "level": "DEBUG",
                       "propagate": True,
                   },
                   "pagure_auth": {
                       "handlers": ["auth_handler"],
                       "level": "DEBUG",
                       "propagate": False,
                   },
                   "flask": {
                       "handlers": ["console"],
                       "level": "INFO",
                       "propagate": False,
                   },
                   "sqlalchemy": {
                       "handlers": ["console"],
                       "level": "WARN",
                       "propagate": False,
                   },
                   "binaryornot": {
                       "handlers": ["console"],
                       "level": "WARN",
                       "propagate": True,
                   },
                   "MARKDOWN": {
                       "handlers": ["console"],
                       "level": "WARN",
                       "propagate": True,
                   },
                   "PIL": {"handlers": ["console"], "level": "WARN", "propagate": True},
                   "chardet": {
                       "handlers": ["console"],
                       "level": "WARN",
                       "propagate": True,
                   },
                   "pagure.lib.encoding_utils": {
                       "handlers": ["console"],
                       "level": "WARN",
                       "propagate": False,
                   },
               },
           }

       NOTE:
          as you can see there is an email handler defined. It's not used anywhere by default but
          you can use it to get report of errors by email and thus monitor your pagure  instance.
          To do this the easiest is to set, on the root logger:

              'handlers': ['console', 'email'],

       NOTE:
          The  pagure_auth  logger  is  a special one logging all activities regarding read/write
          access to git repositories. It will be a pretty important log for auditing  if  needed.
          You can separate this log into its own file if you like by using the following handler:

              "auth_handler": {
                  "formatter": "standard",
                  "class": "logging.handlers.TimedRotatingFileHandler",
                  "filename": "/var/log/pagure/pagure_auth.log",
                  "backupCount": 10,
                  "when": "midnight",
                  "utc": True,
              },

          This  snippet  will  automatically  make the logs rotate at midnight each day, keep the
          logs for 10 days and use UTC as timezone for the logs. Depending  on  how  your  pagure
          instance  is set-up, you may have to tweak the filesystem permissions on the folder and
          file so the rotation works properly.

   ITEM_PER_PAGE
       This configuration key allows you to configure the length of a page by setting the  number
       of items on the page. Items can be commits, users, groups, or projects for example.

       Defaults to: 50.

   PR_TARGET_MATCHING_BRANCH
       If  set  to True, the default target branch for all pull requests in UI is the branch that
       is longest substring of the branch that the pull request is created from. For  example,  a
       mybranch  branch in original repo will be the default target of a pull request from branch
       mybranch-feature-1 in a fork when opening a new pull request. If this is set to False, the
       default branch of the repo will be the default target of all pull requests.

       Defaults to: False.

   SSH_ACCESS_GROUPS
       Some  instances  of  pagure  are  deployed  in such a way that only the members of certain
       groups are allowed to commit via ssh. This  configuration  key  allows  to  specify  which
       groups  have commit access and thus let pagure hide the ssh URL from the drop-down "Clone"
       menu for all the person who are not in one of these groups.  If this configuration key  is
       not  defined  or  left  empty,  it  is  assume that there is no such group restriction and
       everyone can commit via ssh (default behavior).

       Defaults to: []

   SMTP configuration
   SMTP_SERVER
       This configuration key specifies the SMTP server to use when sending emails.

       Defaults to: localhost.

       See also the SMTP_STARTTLS section.

   SMTP_PORT
       This configuration key specifies the SMTP server port.

       SMTP by default uses TCP port 25. The protocol for mail submission is the same,  but  uses
       port  587.   SMTP  connections  secured  by  SSL,  known  as  SMTPS,  default  to port 465
       (nonstandard, but sometimes used for legacy reasons).

       Defaults to: 25

   SMTP_SSL
       This configuration key specifies whether the SMTP connections should be secured over SSL.

       Defaults to: False

   SMTP_STARTTLS
       This configuration key specifies instructs pagure to starts connecting to the SMTP  server
       via a starttls command.

       When  enabling  STARTTLS  in  conjunction  with  a  local  smtp server, you should replace
       localhost with a host name that is included in the server's  certificate.  If  the  server
       only  relays  messages  originating  from  localhost, then you should also ensure that the
       above host name resolves to the same tcp address as localhost, for instance by  adding  an
       appropriate record to /etc/hosts.

       Defaults to: False

   SMTP_KEYFILE
       This  configuration  key  allows  to specify a key file to be used in the starttls command
       when connecting to the smtp server.

       Defaults to: None

   SMTP_CERTFILE
       This configuration key allows to specify a certificate file to be  used  in  the  starttls
       command when connecting to the smtp server.

       Defaults to: None

   SMTP_USERNAME
       This configuration key allows usage of SMTP with auth.

       Note: Specify SMTP_USERNAME and SMTP_PASSWORD for using SMTP auth

       Defaults to: None

   SMTP_PASSWORD
       This configuration key allows usage of SMTP with auth.

       Note: Specify SMTP_USERNAME and SMTP_PASSWORD for using SMTP auth

       Defaults to: None

   SHORT_LENGTH
       This configuration key specifies the length of the commit ids or file hex displayed in the
       user interface.

       Defaults to: 6.

   BLACKLISTED_PROJECTS
       This configuration key specifies a list of project names that are forbidden.  This list is
       used  for  example  to  avoid  conflicts at the URL level between the static files located
       under /static/ and a project that would be named static and thus be located at /static.

       Defaults to:

          [
              'static', 'pv', 'releases', 'new', 'api', 'settings',
              'logout', 'login', 'users', 'groups', 'about'
          ]

   CHECK_SESSION_IP
       This configuration key specifies whether to check the user's IP  address  when  retrieving
       its session. This makes things more secure but under certain setups it might not work (for
       example if there are proxies in front of the application).

       Defaults to: True.

   PAGURE_AUTH
       This configuration key specifies which authentication method to use.   Valid  options  are
       fas, openid, oidc, or local.

       • fas  uses  the  Fedora  Account System FAS <https://admin.fedoraproject.org/accounts> to
         provide user authentication and enforces that users sign the FPCA.

       • openid  uses  OpenID  authentication.   Any  provider  may  be  used  by  changing   the
         FAS_OPENID_ENDPOINT configuration key.  By default FAS (without FPCA) will be used.

       • oidc   enables   OpenID   Connect  using  any  provider.   This  provider  requires  the
         configuration options starting with OIDC_ (see below) to be provided.

       • local causes pagure to use the local pagure database for user management.

       Defaults to: local.

   OIDC Settings
       NOTE:
          Pagure uses flask-oidc to support OIDC authentication. This extension has a  number  of
          configuration keys that may be useful depending on your set-up

   OIDC_CLIENT_SECRETS
       Provide  a path to client secrets file on local filesystem. This file can be obtained from
       your  OpenID  Connect  identity  provider.  Note  that  some  providers  don't   fill   in
       userinfo_uri. If that is the case, you need to add it to the secrets file manually.

   OIDC_ID_TOKEN_COOKIE_SECURE
       When  this  is  set to True, the cookie with OpenID Connect Token will only be returned to
       the server via ssl (https). If you connect to the server via plain http, the  cookie  will
       not be sent. This prevents sniffing of the cookie contents.  This may be set to False when
       testing your application but should always be set to True in production.

       Defaults to: True  for  production  with  https,  can  be  set  to  False  for  convenient
       development.

   OIDC_SCOPES
       List                 of                OpenID                Connect                scopes
       http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims to request from  identity
       provider.

   OIDC_PAGURE_EMAIL
       Name of key of user's email in userinfo JSON returned by identity provider.

   OIDC_PAGURE_FULLNAME
       Name of key of user's full name in userinfo JSON returned by identity provider.

   OIDC_PAGURE_USERNAME
       Name of key of user's preferred username in userinfo JSON returned by identity provider.

   OIDC_PAGURE_SSH_KEY
       Name of key of user's ssh key in userinfo JSON returned by identity provider.

   OIDC_PAGURE_GROUPS
       Name of key of user's groups in userinfo JSON returned by identity provider.

   OIDC_PAGURE_USERNAME_FALLBACK
       This  specifies fallback for getting username assuming OIDC_PAGURE_USERNAME is empty - can
       be email (to use the part before @) or sub (IdP-specific user id, can be a nickname, email
       or a numeric ID depending on identity provider).

   IP_ALLOWED_INTERNAL
       This configuration key specifies which IP addresses are allowed to access the internal API
       endpoint. These endpoints are accessed by the milters for  example  and  allow  performing
       actions  in  the  name  of someone else which is sensitive, thus the origin of the request
       using these endpoints is validated.

       Defaults to: ['127.0.0.1', 'localhost', '::1'].

   MAX_CONTENT_LENGTH
       This configuration key specifies the maximum file size allowed when uploading  content  to
       pagure (for example, screenshots to a ticket).

       Defaults to: 4 * 1024 * 1024 which corresponds to 4 megabytes.

   ENABLE_TICKETS
       This  configuration key activates or deactivates the ticketing system for all the projects
       hosted on this pagure instance.

       Defaults to: True

   ENABLE_TICKETS_NAMESPACE
       This configuration key can be used to restrict the namespace in which the ticketing system
       is   enabled.    So   if  your  pagure  instance  has  ENABLE_TICKETS  as  True  and  sets
       ENABLE_TICKETS_NAMESPACE to ['tests', 'infra'] only  the  projects  opened  in  these  two
       namespaces will have the ticketing system enabled. All the other namespaces will not.

       Defaults to: []

   ENABLE_DOCS
       This  configuration  key  activates or deactivates creation of git repos for documentation
       for all the projects hosted on this pagure instance.

       Defaults to: True

   ENABLE_NEW_PROJECTS
       This configuration key permits or forbids creation of new projects via the user  interface
       and the API of this pagure instance.

       Defaults to: True

   ENABLE_UI_NEW_PROJECTS
       This  configuration key permits or forbids creation of new projects via the user interface
       (only) of this pagure instance. It allows forbidding to create new  project  in  the  user
       interface  while  letting  a  set of trusted person to create projects via the API granted
       they have the API token with the corresponding ACL.

       Defaults to: True

   ENABLE_DEL_PROJECTS
       This configuration key permits or forbids deletion of projects via the user  interface  of
       this pagure instance.

       Defaults to: True

   ENABLE_DEL_FORKS
       This configuration key permits or forbids deletion of forks via the user interface of this
       pagure instance.

       Defaults to: ENABLE_DEL_PROJECTS

   GIT_HOOK_DB_RO
       This configuration key specifies if the git hook have  a  read-only  (RO)  access  to  the
       database  or  not.  Some pagure deployment provide an actual shell account on the host and
       thus the git hook called upon git push are  executed  under  that  account.  If  the  user
       manages  to  by-pass  git  and  is  able to access the configuration file, they could have
       access to "private" information. So in those deployments the git  hooks  have  a  specific
       configuration  file  with  a  database  access  that  is  read-only,  making pagure behave
       differently in those situations.

       Defaults to: False

   EMAIL_SEND
       This configuration key enables  or  disables  all  email  notifications  for  this  pagure
       instance.  This  can  be  useful  to  turn  off  when developing on pagure, or for test or
       pre-production instances.

       Defaults to: False.

       NOTE:
          This does not disable emails to the email address set in EMAIL_ERROR.

   FEDMSG_NOTIFICATIONS
       This configuration key can be used to turn on or off notifications via fedmsg.

       Defaults to: False.

   FEDORA_MESSAGING_NOTIFICATIONS
       This configuration  key  can  be  used  to  turn  on  or  off  sending  notifications  via
       fedora-messaging.

       Defaults to: False.

   ALWAYS_FEDMSG_ON_COMMITS
       This  configuration key can be used to enforce fedmsg notifications on commits made on all
       projects in a pagure instance.

       Defaults to: True.

   ALLOW_DELETE_BRANCH
       This configuration keys enables or disables allowing users to delete git branches from the
       user  interface.  In  sensible  pagure  instance  you may want to turn this off and with a
       customized gitolite configuration you can prevent users from deleting  branches  in  their
       git repositories.

       Defaults to: True.

   ALLOW_ADMIN_IGNORE_EXISTING_REPOS
       This  enables  a  checkbox "Ignore existing repos" for admins when creating a new project.
       When this is checkbox is checked, existing repositories will not cause project creation to
       fail.  This could be used to assume responsibility of existing repositories.

       Defaults to: False.

   USERS_IGNORE_EXISTING_REPOS
       List of users who can al create a project while ignoring existing repositories.

       Defaults to: [].

   LOCAL_SSH_KEY
       This  configuration key can be used to let pagure administrate the user's ssh keys or have
       a third party tool do it for you.  In most cases, it will be fine to let pagure handle it.

       Defaults to True.

   DEPLOY_KEY
       This configuration key can be used to disable the deploy keys feature of an entire  pagure
       instance. This feature enable to add extra public ssh keys that a third party could use to
       push to a project.

       Defaults to True.

   OLD_VIEW_COMMIT_ENABLED
       In version 1.3, pagure changed its URL scheme to view the commit of a project in order  to
       add support for pseudo-namespaced projects.

       For  pagure  instances  older than 1.3, who care about backward compatibility, we added an
       endpoint view_commit_old that  brings  URL  backward  compatibility  for  URLs  using  the
       complete  git  hash  (the  40  characters).   For URLs using a shorter hash, the URLs will
       remain broken.

       This configuration key enables or disables this backward compatibility which is useful for
       pagure instances running since before 1.3 but is not for newer instances.

       Defaults to: False.

   DISABLE_REMOTE_PR
       In  some pagure deployments remote pull requests need to be disabled due to legal / policy
       reasons.

       Defaults to: False.

   PAGURE_CI_SERVICES
       Pagure can be configure to integrate results of a Continuous Integration (CI)  service  to
       pull-requests open against a project.

       To  enable  this integration, follow the documentation on how to install pagure-ci and set
       this configuration key to ['jenkins'] (Jenkins being the only CI service supported at  the
       moment).

       Defaults to: None.

       WARNING:
          Requires Redis to be configured and running.

   INSTANCE_NAME
       This allows giving a name to this running instance of pagure. The name is then used in the
       welcome screen shown upon first login.

       Defaults to: Pagure

   ADMIN_EMAIL
       This configuration key allows you to change  the  default  administrator  email  which  is
       displayed on the "about" page. It can also be used elsewhere.

       Defaults to: root@localhost.localdomain

   USER_NAMESPACE
       This configuration key can be used to enforce that project are namespaced under the user's
       username, behaving in this way in a similar fashion as github.com or gitlab.com.

       Defaults to: False

   DOC_APP_URL
       This configuration key allows you to specify where the  documentation  server  is  running
       (preferably in a different domain name entirely).  If not set, the documentation page will
       show an error message saying that this pagure  instance  does  not  have  a  documentation
       server.

       Defaults to: None

   PRIVATE_PROJECTS
       This  configuration  key  allows  you to host private repositories. These repositories are
       visible only to the creator of the repository and to the users who are given access to the
       repository.  No  information  is  leaked  about  the  private repository which means redis
       doesn't have the access to the repository and even fedmsg doesn't get any notifications.

       Defaults to: True

   EXCLUDE_GROUP_INDEX
       This configuration key can be used to hide project an user has access to via  one  of  the
       groups listed in this key.

       The  use-case is the following: the Fedora project is deploying pagure has a front-end for
       the git  repos  of  the  packages  in  the  distribution,  that  means  about  17,000  git
       repositories in pagure. The project has a group of people that have access to all of these
       repositories, so when viewing the user's page of one member  of  that  group,  instead  of
       seeing  all  the  project  that this user works on, you can see all the projects hosted in
       that pagure instance. Using this configuration key, pagure will hide all the projects that
       this  user has access to via the specified groups and thus return only the groups of forks
       of that users.

       Defaults to: []

   TRIGGER_CI
       A run of pagure-ci can be manually triggered if some key sentences are added as comment to
       a pull-request, either manually or via the "Rerun CI" dropdown.  This allows one to re-run
       a test that failed due to some network outage or other unexpected issues unrelated to  the
       test suite.

       This configuration key can be used to define all the sentences that can be used to trigger
       this pagure-ci run. The format is following: {"<sentence>": {"name": "<name of  the  CI>",
       "description": "<short description>"}}

       Sentences which have None as value won't show up in the "Rerun CI" dropdown. Additionally,
       it's possible to add a requires_project_hook_attr key  to  the  dict  with  data  about  a
       sentence. For example, having "requires_project_hook_attr": ("ci_hook", "active_pr", True)
       would make the "Rerun CI" dropdown have a button for this specific CI only if the  project
       has ci_hook activated and its active_pr value is True.

       In versions before 5.2, this was a list containing just the sentences.

       Defaults  to:  {"pretty  please  pagure-ci rebuild": {"name": "Default CI", "description":
       "Rerun default CI"}}

       NOTE:
          The sentences defined in this configuration key should be lower case only!

   FLAG_STATUSES_LABELS
       By default, Pagure has success, failure, error, pending and canceled statuses  of  PR  and
       commit  flags.  This  setting  allows  you to define a custom mapping of statuses to their
       respective Bootstrap labels.

   FLAG_SUCCESS
       Holds name of PR/commit flag that is considered a success.

       Defaults to: success

   FLAG_FAILURE
       Holds name of PR/commit flag that is considered a failure.

       Defaults to: failure

   FLAG_PENDING
       Holds name of PR/commit flag that is considered a pending state.

       Defaults to: pending

   EXTERNAL_COMMITTER
       The external committer feature is a way to allow members of groups defined outside  pagure
       (and provided to pagure upon login by the authentication system) to be consider committers
       on pagure.

       This feature can give access to all the projects on the instance, all  but  some  or  just
       some.

       Defaults to: {}

       To give access to all the projects to a group named fedora-altarch use a such a structure:

          EXTERNAL_COMMITTER = {
              'fedora-altarch': {}
          }

       To  give  access  to  all  the  projects  but  one  (named  rpms/test)  to  a  group named
       provenpackager use a such a structure:

          EXTERNAL_COMMITTER = {
              'fedora-altarch': {},
              'provenpackager': {
                  'exclude': ['rpms/test']
              }
          }

       To give access to just some projects (named rpms/test and modules/test) to a  group  named
       testers use a such a structure:

          EXTERNAL_COMMITTER = {
              'fedora-altarch': {},
              'provenpackager': {
                  'exclude': ['rpms/test']
              },
              'testers': {
                  'restrict': ['rpms/test', 'modules/test']
              }
          }

   REQUIRED_GROUPS
       The  required groups allows one to specify in which group an user must be to be added to a
       project with commit or admin access.

       Defaults to: {}

       Example configuration:

          REQUIRED_GROUPS = {
              'rpms/kernel': ['packager', 'kernel-team'],
              'modules/*': ['module-packager', 'packager'],
              'rpms/*': ['packager'],
              '*': ['contributor'],
          }

       With this configuration (evaluated in the provided order):

       • only users that are in the groups packager and kernel-team will be allowed to  be  added
         the rpms/kernel project (where rpms is the namespace and kernel the project name).

       • only  users  that  are  in the groups module-packager and packager will be allowed to be
         added to projects in the modules namespace.

       • only users that are in the group packager will be allowed to be added to projects in the
         rpms namespace.

       • only  users  in the contributor group will be allowed to be added to any project on this
         pagure instance.

   GITOLITE_PRE_CONFIG
       This configuration key allows you to include some content  at  the  top  of  the  gitolite
       configuration  file  (such  as some specific group definition), thus allowing to customize
       the gitolite configuration file with elements and information that are outside of pagure's
       control.

       This  can be used in combination with GITOLITE_POST_CONFIG to further customize gitolite's
       configuration file. It can also be used with EXTERNAL_COMMITTER to give commit  access  to
       git repos based on external information.

       Defaults to: None

   GITOLITE_POST_CONFIG
       This  configuration  key  allows  you  to  include some content at the end of the gitolite
       configuration file (such as some project definition or access), thus allowing to customize
       the gitolite configuration file with elements and information that are outside of pagure's
       control.

       This can be used in combination with GITOLITE_PRE_CONFIG to further  customize  gitolite's
       configuration  file.  It can also be used with EXTERNAL_COMMITTER to give commit access to
       git repos based on external information.

       Defaults to: None

   GIT_GARBAGE_COLLECT
       This configuration key allows for explicit running of git gc --auto after every  operation
       that  adds  new  objects  to  any  git repository - that is after pushing and merging. The
       reason for having this functionality in Pagure is that gc is not guaranteed to be  run  by
       git after every object-adding operation.

       The  garbage  collection run by Pagure will respect git settings, so you can tweak gc.auto
       and gc.autoPackLimit to your liking and that will have immediate effect on the  task  that
       runs the garbage collection. These values can be configured system-wide in /etc/gitconfig.
       See https://git-scm.com/docs/git-gc#git-gc---auto for more details.

       This is especially useful if repositories are stored on NFS (or similar network  storage),
       where file metadata access is expensive - having unpacked objects in repositories requires
       a lot of metadata reads.

       Note that the garbage collection is only run on repos that are not on repoSpanner.

       Defaults to: False

   CELERY_CONFIG
       This configuration key allows you to tweak the configuration of  celery  for  your  needs.
       See the documentation about celery configuration for more information.

       Defaults to: {}

   CASE_SENSITIVE
       This  configuration key can be used to make this pagure instance case sensitive instead of
       its default: case-insensitive.

       Defaults to: False

   PROJECT_NAME_REGEX
       This configuration key can be used to customize the regular expression  used  to  validate
       new project name.

       Defaults to: ^[a-zA-z0-9_][a-zA-Z0-9-_]*$

   APPLICATION_ROOT
       This configuration key is used in the path of the cookie used by pagure.

       Defaults to: '/'

   ALLOWED_PREFIX
       This  configuration  key can be used to specify a list of allowed namespaces that will not
       require creating a group for users to create projects in.

       Defaults to: []

   ADMIN_SESSION_LIFETIME
       This configuration key allows specifying the lifetime of the session during which the user
       won't  have to re-login for admin actions.  In other words, the maximum time between which
       an user can access a project's settings page without re-login.

       Defaults to: timedelta(minutes=20)

       where timedelta comes from the python datetime module

   BLACKLISTED_GROUPS
       This configuration key can be used to blacklist some group names.

       Defaults to: ['forks', 'group']

   ENABLE_GROUP_MNGT
       This configuration key can be used to turn on or  off  managing  (ie:  creating  a  group,
       adding  or  removing  users in that group) groups in this pagure instance.  If turned off,
       groups and group members are to be managed outside of pagure and synced upon login.

       Defaults to: True

   ENABLE_USER_MNGT
       This configuration key can be used to turn on or off managing users  (adding  or  removing
       them from a project) in this pagure instance.  If turned off, users are managed outside of
       pagure.

       Defaults to: True

   SESSION_COOKIE_NAME
       This configuration key can be used to specify the name  of  the  session  cookie  used  by
       pagure.

       Defaults to: 'pagure'

   SHOW_PROJECTS_INDEX
       This configuration key can be used to specify what is shown in the index page of logged in
       users.

       Defaults to: ['repos', 'myrepos', 'myforks']

   EMAIL_ON_WATCHCOMMITS
       By default pagure sends an email to every one watch commits on a project when a commit  is
       made.   However  some  pagure instances may be using a different notification mechanism on
       commits and thus may not want this feature to double  the  notifications  received.   This
       configuration  key  can  be  used  to  turn  on or off email being sent to people watching
       commits on a project upon commits.

       Defaults to: True

   ALLOW_HTTP_PULL_PUSH
       This configuration key controls whether any HTTP access to repositories  is  provided  via
       the  support  for  that  that's  embedded  in  Pagure.  This provides HTTP pull access via
       <pagureurl>/<reponame>.git if nothing else serves this URL.

       Defaults to: True

   ALLOW_HTTP_PUSH
       This configuration key controls whether pushing is possible via the HTTP interface.   This
       is  disabled  by  default,  as  it  requires setting up an authentication mechanism on the
       webserver that sets REMOTE_USER.

       Defaults to: False

   HTTP_REPO_ACCESS_GITOLITE
       This configuration key configures the path to the gitolite-shell binary.  If this  is  set
       to  None,  Git  http-backend  is  used  directly.   Only set this to None if you intend to
       provide HTTP push access via Pagure, and are using a dynamic ACL backend.

       Defaults to: /usr/share/gitolite3/gitolite-shell

   MIRROR_SSHKEYS_FOLDER
       This configuration key specificies where pagure should store the ssh  keys  generated  for
       the mirroring feature. This folder should be properly backed up and kept secure.

       Defaults to: /var/lib/pagure/sshkeys/

   LOG_ALL_COMMITS
       This  configuration  key  will  make  pagure log all commits pushed to all branches of all
       repositories instead of logging only the once that are pushed to the default branch.

       Defaults to: False

   DISABLE_MIRROR_IN
       This configuration key allows a pagure instance to not support mirroring in projects (from
       third party git server).

       Defaults to: False

   SYNTAX_ALIAS_OVERRIDES
       This configuration key can be used to force highlight.js to use a certain logic on certain
       files based on their extensions.

       It should be a dictionary containing the file extensions  as  keys  and  the  highlighting
       language/category to use as values.

       Defaults to: {".spec": "specfile", ".patch": "diff"}

   ALLOW_API_UPDATE_GIT_TAGS
       This  configuration  key  determines whether users are allowed to update existing git tags
       via the API.  When set to False, this essentially makes the API ignore whether  the  force
       argument is set or not.

       Default to: True

   RepoSpanner Options
       Pagure  can  be  integrated  with repoSpanner allowing to deploy pagure in a load-balanced
       environment  since  the  git  repositories  are  then  synced  across   multiple   servers
       simultaneously.

       Support for this integration has been included in Pagure version 5.0 and higher.

       Here  below  are  the  different  options  one  can/should  use  to  integrate pagure with
       repoSpanner.

   REPOBRIDGE_BINARY
       This should contain the path to the repoBridge binary,  which  is  used  for  pushing  and
       pulling to/from repoSpanner.

       Defaults to: /usr/libexec/repobridge.

   REPOSPANNER_NEW_REPO
       This  configuration  key instructs pagure to create new git repositories on repoSpanner or
       not.  Its value should be the region in which the new git repositories should  be  created
       on.

       Defaults to: None.

   REPOSPANNER_NEW_REPO_ADMIN_OVERRIDE
       This  configuration  key  can be used to let pagure admin override the default region used
       when creating new git repositories on repoSpanner.  Its value should be a boolean.

       Defaults to: False

   REPOSPANNER_NEW_FORK
       This configuration key instructs pagure on where/how to create new  git  repositories  for
       the  forks  with  repoSpanner.  If None, git repositories for forks are created outside of
       repoSpanner entirely.  If True, git repositories for forks are created in the same  region
       as  the  parent  project.   Otherwise,  a  region  can  be  directly  specified  where git
       repositories for forks will be created.

       Defaults to: True

   REPOSPANNER_ADMIN_MIGRATION
       This configuration key can be used to let admin manually migrate individual  project  into
       repoSpanner once it is set up.

       Defaults to: False

   REPOSPANNER_REGIONS
       This  configuration  key  can be used to specify the different region where repoSpanner is
       deployed and thus with which this pagure instance can be integrated.

       An example entry could look like:

          REPOSPANNER_REGIONS = {
              'default': {'url': 'https://nodea.regiona.repospanner.local:8444',
                          'repo_prefix': 'pagure/',
                          'hook': None,
                          'ca': '/etc/pki/repospanner/pki/ca.crt',
                          'admin_cert': {'cert': '/etc/pki/repospanner/pki/admin.crt',
                                         'key': '/etc/pki/repospanner/pki/admin.key'},
                          'push_cert': {'cert': '/etc/pki/repospanner/pki/pagure.crt',
                                        'key': '/etc/pki/repospanner/pki/pagure.key'}}
          }

       If this configuration key is not defined, pagure will consider that it is not  set  to  be
       integrated with repoSpanner.

       Defaults to: {}

   SSH_KEYS_USERNAME_LOOKUP
       This  configuration  key is used by the keyhelper script to indicate that the git username
       should be used and looked up. Use this if the username that is sent to ssh is specific for
       a unique Pagure user (i.e. not using a single "git@" user for all git operations).

   SSH_KEYS_USERNAME_FORBIDDEN
       A list of usernames that are exempted from being verified via the keyhelper.

   SSH_KEYS_USERNAME_EXPECT
       This  configuration  key  should contain the username that is used for git if a single SSH
       user is used for all git ssh traffic (i.e. "git").

   SSH_KEYS_OPTIONS
       This configuration key provides the options added to keys as they are returned to sshd, in
       the same format as AuthorizedKeysFile (see "AUTHORIZED_KEYS FILE FORMAT" in sshd(8)).

   SSH_ADMIN_TOKEN
       If  not  set  to  None,  aclchecker  and  keyhelper  will  use this api admin token to get
       authorized to internal endpoints that they use. The token must  have  the  internal_access
       ACL.

       This  is  useful  when  the IP address of sshd service is not predictable (e.g. because of
       running in a  distributed  cloud  environment)  and  so  it's  not  possible  to  use  the
       IP_ALLOWED_INTERNAL address list.

       Defaults to: None

   SSH_COMMAND_REPOSPANNER
       The command to run if a repository is on repospanner when aclchecker is in use.

   SSH_COMMAND_NON_REPOSPANNER
       The command to run if a repository is not on repospanner when aclchecker is in use.

   MQTT Options
       If approprietly configured pagure supports sending messages to an MQTT message queue.

       Here below are the different configuration options to make it so.

   MQTT_NOTIFICATIONS
       Global  configuration  key  to  turn  on  or off the code to send notifications to an MQTT
       message queue.

       Defaults to: False

   MQTT_HOST
       Host name of the MQTT server to send the MQTT notifications to.

       Defaults to: None

   MQTT_PORT
       Port of the MQTT server to use to send the MQTT notifications to.

       Defaults to: None

   MQTT_USERNAME
       Username to authenticate to the MQTT server as.

       Defaults to: None

   MQTT_PASSWORD
       Password to authenticate to the MQTT server with.

       Defaults to: None

   MQTT_CA_CERTS
       When using SSL-based authentication to the MQTT server,  use  this  configuration  key  to
       point to the CA cert to use.

       Defaults to: None

   MQTT_CERTFILE
       When  using  SSL-based  authentication  to  the MQTT server, use this configuration key to
       point to the cert file to use.

       Defaults to: None

   MQTT_KEYFILE
       When using SSL-based authentication to the MQTT server,  use  this  configuration  key  to
       point to the key file to use.

       Defaults to: None

   MQTT_CERT_REQS
       When  using  SSL-based  authentication  to  the MQTT server, use this configuration key to
       specify if the CERT is required.

       Defaults to: ssl.CERT_REQUIRED (from python's ssl library)

   MQTT_TLS_VERSION
       When using SSL-based authentication to the MQTT server,  use  this  configuration  key  to
       specify the TLS protocols to support/use.

       Defaults to: ssl.PROTOCOL_TLSv1_2 (from python's ssl library)

   MQTT_CIPHERS
       When  using  SSL-based  authentication  to  the MQTT server, use this configuration key to
       specify the ciphers.

       Defaults to: None

   MQTT_TOPIC_PREFIX
       This configuration key can be used to specify a prefix to the mqtt  messages  sent.   This
       prefix  will be added to the topic used by pagure thus allowing the mqtt admins to specify
       a parent topic for all pagure-related messages.

       Defaults to: None

   ALWAYS_MQTT_ON_COMMITS
       This configuration key can be used to enforce mqtt notifications on commits  made  on  all
       projects in a pagure instance.

       Defaults to: False.

   PAGURE_PLUGINS_CONFIG
       This  option can be used to specify the configuration file used for loading plugins. It is
       not set by default, instead if must be declared explicitly.  Also see the documentation on
       plugins at Plugins.

   Deprecated configuration keys
   FORK_FOLDER
       This  configuration  key  used to be use to specify the folder where the forks are placed.
       Since the release 2.0 of pagure, it has  been  deprecated,  forks  are  now  automatically
       placed  in  a  sub-folder  of  the  folder  containing  the  mains  git  repositories  (ie
       GIT_FOLDER).

       See the UPGRADING.rst file for more information about this change and how to handle it.

   UPLOAD_FOLDER
       This configuration key used  to  be  use  to  specify  where  the  uploaded  releases  are
       available. It has been replaced by UPLOAD_FOLDER_PATH in the release 2.10 of pagure.

   GITOLITE_VERSION
       This configuration key specifies which version of gitolite you are using, it can be either
       2 or 3.

       Defaults to: 3.

       This has been replaced by GITOLITE_BACKEND in the release 3.0 of pagure.

   DOCS_FOLDER, REQUESTS_FOLDER, TICKETS_FOLDER
       These configuration values were removed. It has been found out  that  due  to  how  Pagure
       writes repo names in the gitolite configuration file, these must have fixed paths relative
       to GIT_FOLDER. Specifically, they must occupy subdirectories docs,  requests  and  tickets
       under  GIT_FOLDER.   They  are  now  computed  automatically based on value of GIT_FOLDER.
       Usage of docs and tickets can be triggered by setting ENABLE_DOCS  and  ENABLE_TICKETS  to
       True (this is the default).

   FILE_SIZE_HIGHLIGHT
       This  configuration  key can be used to specify the maximum number of characters a file or
       diff should have to have syntax highlighting. Everything above this limit  will  not  have
       syntax  highlighting  as  this is a memory intensive procedure that easily leads to out of
       memory error on large files or diff.

       Defaults to: 5000

   BOOTSTRAP_URLS_CSS
       This configuration key can be used to specify the URL where are hosted the  bootstrap  CSS
       file since the files hosted on apps.fedoraproject.org used in pagure.io are not restricted
       in browser access.

       Defaults                                                                               to:
       'https://apps.fedoraproject.org/global/fedora-bootstrap-1.1.1/fedora-bootstrap.css'

       This has been deprecated by the new way of theming pagure, see the theming documentation

   BOOTSTRAP_URLS_JS
       This  configuration  key  can be used to specify the URL where are hosted the bootstrap JS
       file since the files hosted on apps.fedoraproject.org used in pagure.io are not restricted
       in browser access.

       Defaults                                                                               to:
       'https://apps.fedoraproject.org/global/fedora-bootstrap-1.1.1/fedora-bootstrap.js'

       This has been deprecated by the new way of theming pagure, see the theming documentation

   HTML_TITLE
       This configuration key allows you to customize the HTML title of all the pages, from ... -
       pagure (default) to ... - <your value>.

       Defaults to: Pagure

       This has been deprecated by the new way of theming pagure, see the theming documentation

   GITOLITE_BACKEND
       This  configuration  key  allowed  specifying  the  gitolite  backend.   This has now been
       replaced by GIT_AUTH_BACKEND, please see that option for information on valid values.

   PAGURE_PLUGIN
       This configuration key allows to specify the path to the plugins configuration file. It is
       set  as  an  environment  variable. It has been replaced by PAGURE_PLUGINS_CONFIG. The new
       variable does not modify the behavior of the old variable, however unlike PAGURE_PLUGIN it
       can be set in the main Pagure configuration.

PLUGINS

       Pagure provides a mechanism for loading 3rd party plugins in the form of Flask Blueprints.
       The plugins are loaded from a separate configuration file  that  is  specified  using  the
       PAGURE_PLUGINS_CONFIG  option.  There  are  at  least  two  reasons  for  keeping  plugins
       initialization outside the main pagure configuration file:

       1. avoid circular dependencies errors. For example if the pagure configuration  imports  a
          plugin,  which in turn imports the pagure configuration, the plugin could try to read a
          configuration option that has not been imported yet and thus raise an error

       2. the pagure configuration is also loaded by other processes such as Celery workers.  The
          Celery  tasks  might  only  be interested in reading the configuration settings without
          having to load any external plugin

   Loading the configuration
       The configuration file can be loaded by setting the variable PAGURE_PLUGINS_CONFIG  inside
       the   pagure   main   configuration   file,  for  example  inside  /etc/pagure/pagure.cfg.
       Alternatively, it is also possible to set the environment  variable  PAGURE_PLUGINS_CONFIG
       before  starting  the  pagure  server. If both variables are set, the environment variable
       takes precedence over the configuration file.

   The configuration file
       After Pagure has imported the configuration file defined in PAGURE_PLUGINS_CONFIG it  will
       look  for  Flask  Blueprints  in  a  variable called PLUGINS defined in the same file, for
       example PLUGINS = [ plugin1.blueprint, plugin2.blueprint, ... ]. Pagure will then  proceed
       to register any Blueprint into the main Flask app, in the same order as they are listed in
       PLUGINS.

       An example configuration  can  be  seen  in  files/plugins.cfg.sample  inside  the  Pagure
       repository.

CUSTOMIZE THE GITOLITE CONFIGURATION

       Pagure  provides  a  mechanism  to  allow  customizing the creation and compilation of the
       configuration file of gitolite.

       To customize the gitolite configuration file, we invite you to look at the sources of  the
       module pagure.lib.git_auth.

       As you can see it defines the following class:

          class GitAuthHelper(object):

              __metaclass__ = abc.ABCMeta

              @staticmethod
              @abc.abstractmethod
              def generate_acls():
                  pass

              @classmethod
              @abc.abstractmethod
              def remove_acls(self, session, project):
                  pass

       This  will  be  the  class you will have to inherit from in order to inject your own code.
       You will then declare an entry point in your setup.py following this template:

          entry_points="""
          [pagure.git_auth.helpers]
          my_git_auth = my_pagure.my_module:MyGitAuthTestHelper
          """

       Then you can adjust pagure's configuration file to say:

          GITOLITE_BACKEND = 'my_git_auth'

DEVELOPMENT

   Get the sources
       Anonymous:

          git clone https://pagure.io/pagure.git

       Contributors:

          git clone ssh://git@pagure.io/pagure.git

   Dependencies
       Install the build dependencies of pagure:

          sudo dnf install git python-virtualenv libgit2-devel \
                           libjpeg-devel gcc libffi-devel redhat-rpm-config

       The python dependencies of pagure are listed in the file requirements.txt at the top level
       of the sources.

          virtualenv pagure_env
          source ./pagure_env/bin/activate
          pip install pygit2==<version of libgit2 found>.* # e.g. 0.23.*
          pip install -r requirements.txt

       NOTE:
          working  in  a virtualenv is tricky due to the dependency on pygit2 and thus on libgit2
          but the pygit2 documentation has a solution for this.

   How to run pagure
       There are several options when it comes to a development environment. Vagrant will provide
       you with a virtual machine which you can develop on, you can use a container to run pagure
       or you can install it directly on your host machine.  The README has detailed instructions
       for the different options.

   Run pagure for development
       Adjust   the   configuration   file  (secret  key,  database  URL,  admin  group...)   See
       Configuration for more detailed information about the configuration.

       Create the database scheme:

          ./createdb.py

       Create the folder that will receive the different git repositories:

          mkdir {repos,docs,forks,tickets,requests,remotes}

       Run the server:

          ./runserver.py

       If you  want  to  change  some  configuration  key  you  can  create  a  file,  place  the
       configuration change in it and use it with

          ./runserver.py -c <config_file>

       For example, create the file config with in it:

          from datetime import timedelta
          # Makes the admin session longer
          ADMIN_SESSION_LIFETIME = timedelta(minutes=20000000)

          # Use a postgresql database instead of sqlite
          DB_URL = 'postgresql://user:pass@localhost/pagure'
          # Change the OpenID endpoint
          FAS_OPENID_ENDPOINT = 'https://id.stg.fedoraproject.org'

          APP_URL = '*'
          EVENTSOURCE_SOURCE = 'http://localhost:8080'
          EVENTSOURCE_PORT = '8080'
          DOC_APP_URL = '*'

          # Avoid sending email when developing
          EMAIL_SEND = False

       and run the server with:

          ./runserver.py -c config

       To get some profiling information you can also run it as:

          ./runserver.py --profile

       You should be able to access the server at http://localhost:5000

       Every  time  you  save  a file, the project will be automatically restarted so you can see
       your change immediately.

   Create a pull-request for testing
       When working on pagure, it is pretty often that one wanted to work on a feature or  a  bug
       related to pull-requests needs to create one.

       Making  a  pull-request  for  development  purposes isn't hard, if you remember that since
       you're running a local instance, the git repos created in your pagure  instance  are  also
       local.

       So  here  are  in  a  few steps that one could perform to create a pull-request in a local
       pagure instance.

       • Create a project on your pagure instance, let's say it will be called test

       • Create a folder clones somewhere in your system (you probably do  not  want  it  in  the
         repos folder created above, next to it is fine though):

            mkdir clones

       • Clone the repo of the test project into this clones folder and move into it:

            cd clones
            git clone ~/path/to/pagure/repos/test.git
            cd test

       • Add and commit some files:

            echo "*~" > .gitignore
            git add .gitignore
            git commit -m "Add a .gitignore file"
            echo "BSD" > LICENSE
            git add LICENSE
            git commit -m "Add a LICENSE file"

       • Push these changes:

            git push -u origin master

       • Create a new branch and add a commit in it:

            git branch new_branch
            git checkout new_branch
            touch test
            git add test
            git commit -m "Add file: test"

       • Push this new branch:

            git push -u origin new_branch

       Then  go back to your pagure instance running in your web-browser, check the test project.
       You should see two branches: master and new_branch.  From there you should be able to open
       a  new pull-request, either from the front page or via the File Pull Request button in the
       Pull Requests page.

   Coding standards
       We are trying to  make  the  code  PEP8-compliant.   There  is  a  flake8  tool  that  can
       automatically check your source.

       We  run  the  source  code  through black as part of the tests, so you may have to do some
       adjustments or run it yourself (which is simple: black /path/to/pagure).

       NOTE:
          flake8 and black are available in Fedora:

              dnf install python3-flake8 python3-black

          or

              yum install python3-flake8 python3-black

   Send patch
       The easiest way to work on pagure is to make your own branch in git, make your changes  to
       this  branch,  commit  whenever you want, rebase on master, whenever you need and when you
       are done, send the patch either by email, via the trac or a  pull-request  (using  git  or
       github).

       The workflow would therefore be something like:

          git branch <my_shiny_feature>
          git checkout <my_shiny_feature>
          <work>
          git commit file1 file2
          <more work>
          git commit file3 file4
          git checkout master
          git pull
          git checkout <my_shiny_feature>
          git rebase master
          git format-patch -2

       This  will  create  two  patch  files  that you can send by email to submit in a ticket on
       pagure, by email or after forking the project on pagure by submitting a  pull-request  (in
       which case the last step above git format-patch -2 is not needed.

       NOTE:
          Though  not  required, it’s a good idea to begin the commit message with a single short
          (less than 50 character) line summarizing the change, followed by a blank line and then
          a  more  thorough description.  The text up to the first blank line in a commit message
          is treated as the commit title, and that title is used throughout  Git.   For  example,
          git-format-patch  turns  a commit into email, and it uses the title on the Subject line
          and the rest of the commit in the body.  Pagure uses lines  that  contain  only  'Fixes
          #number' as references to issues. If for example a commit message of a pagure patch has
          a line 'Fixes #3547' and a pullrequest (PR) gets created in pagure,  this  PR  will  be
          linked to from https://pagure.io/pagure/issue/3547

   Unit-tests
       Pagure has a number of unit-tests.

       We  aim  at  having  a  full  (100%)  coverage  of  the  whole  code  (including the Flask
       application) and of course a smart coverage as in we want to check that the functions work
       the way we want but also that they fail when we expect it and the way we expect it.

       Tests  checking  that  function  are  failing  when/how  we want are as important as tests
       checking they work the way they are intended to.

       So here are a few steps that one could  perform  to  run  unit-tests  in  a  local  pagure
       instance.

       • Install the dependencies:

            pip install -r requirements-testing.txt

       • Run it:

            tox ./test/

       If you want to run a single interpreter, cou can use:

          tox -e py38 ./test/

       Each  unit-tests  files  (located  under  tests/)  can be called by alone, allowing easier
       debugging of the tests. For example:

          pytest-3 tests/test_pagure_lib.py

       NOTE:
          In order to have coverage information you might have to install python-coverage

              dnf install python3-pytest-cov

       To run the unit-tests, there is also a  container  available  with  all  the  dependencies
       needed.  Use the following command to run the tests

          $ ./dev/run-tests-container.py

       This command will build a fedora based container and execute the test suite.  You can also
       limit the tests to unit-test files or single tests similar to the options described above.
       You  need set the environment variables REPO and BRANCH if the tests are not yet available
       in the upstream pagure master branch.

CONTRIBUTING

       If you're submitting patches to pagure, please observe the following:

       • Check  that  your  python  code  is  PEP8-compliant.   There  is  a  flake8  tool   that
         automatically checks the sources as part of the tests.

       • We  run  the  source code through black as part of the tests, so you may have to do some
         adjustments or run it yourself (which is simple: black /path/to/pagure).

       • Check that your code doesn't break the test suite.  The test suite can be run using  tox
         at  the  top  of  the sources, you mayuse tox -e py38 ./test/ to run a single version of
         python.  You  can  also  run  a  single  file  by  calling  pytest  directly:   pytest-3
         tests/test_style.py.  See Development for more information about the test suite.

       • If  you  are  adding new code, please write tests for them in tests/, tox . will run the
         tests and show you the coverage of the code by the unit-tests.

       • If your change warrants a modification to the docs in doc/ or any docstrings in  pagure/
         please make that modification.

       NOTE:
          You  have  a doubt, you don't know how to do something, you have an idea but don't know
          how to implement it, you just have something bugging you?

          Come to see us on IRC: #pagure or #fedora-apps on irc.freenode.net or directly  on  the
          project.

CONTRIBUTORS TO PAGURE

       Pagure would be nothing without its contributors.

       On May 14, 2019 (release 5.10.0) the list looks as follow:

                        ┌──────────────────┬───────────────────────────────────┐
                        │Number of commits │ Contributor                       │
                        ├──────────────────┼───────────────────────────────────┤
                        │6799              │ Pierre-Yves       Chibon      <‐  │
                        │                  │ pingou@pingoured.fr>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │328               │ Ryan Lerch <rlerch@redhat.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │172               │ Vivek          Anand          <‐  │
                        │                  │ vivekanand1101@gmail.com>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │144               │ Julen    Landa    Alustiza    <‐  │
                        │                  │ jlanda@fedoraproject.org>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │139               │ farhaanbukhsh                 <‐  │
                        │                  │ farhaan.bukhsh@gmail.com>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │134               │ Clement         Verna         <‐  │
                        │                  │ cverna@tutanota.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │133               │ Patrick       Uiterwijk       <‐  │
                        │                  │ puiterwijk@redhat.com>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │98                │ Patrick       Uiterwijk       <‐  │
                        │                  │ patrick@puiterwijk.org>           │
                        └──────────────────┴───────────────────────────────────┘

                        │88                │ Farhaan        Bukhsh         <‐  │
                        │                  │ farhaan.bukhsh@gmail.com>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │64                │ Slavek         Kabrda         <‐  │
                        │                  │ bkabrda@redhat.com>               │
                        ├──────────────────┼───────────────────────────────────┤
                        │59                │ Johan       Cwiklinski        <‐  │
                        │                  │ johan@x-tnd.be>                   │
                        ├──────────────────┼───────────────────────────────────┤
                        │52                │ Karsten          Hopp         <‐  │
                        │                  │ karsten@redhat.com>               │
                        ├──────────────────┼───────────────────────────────────┤
                        │47                │ Mark         Reynolds         <‐  │
                        │                  │ mreynolds@redhat.com>             │
                        ├──────────────────┼───────────────────────────────────┤
                        │36                │ Neal Gompa <ngompa13@gmail.com>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │33                │ Lubomír         Sedlář        <‐  │
                        │                  │ lsedlar@redhat.com>               │
                        ├──────────────────┼───────────────────────────────────┤
                        │32                │ Matt Prahl <mprahl@redhat.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │32                │ Pradeep     CE     (cep)      <‐  │
                        │                  │ breathingcode@gmail.com>          │
                        ├──────────────────┼───────────────────────────────────┤
                        │25                │ Lubomír         Sedlář        <‐  │
                        │                  │ lubomir.sedlar@gmail.com>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │23                │ rahul Bajaj <you@example.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │20                │ Jeremy Cline <jeremy@jcline.org>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │19                │ Aurélien       Bompard        <‐  │
                        │                  │ aurelien@bompard.org>             │
                        ├──────────────────┼───────────────────────────────────┤
                        │19                │ Fabien         Boucher        <‐  │
                        │                  │ fboucher@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │19                │ Gaurav Kumar <aavrug@gmail.com>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │19                │ Lenka Segura <lenka@sepu.cz>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │18                │ Abhijeet       Kasurde        <‐  │
                        │                  │ akasurde@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │18                │ Sayan        Chowdhury        <‐  │
                        │                  │ sayan.chowdhury2012@gmail.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │17                │ Adam        Williamson        <‐  │
                        │                  │ awilliam@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │17                │ Brian         Stinson         <‐  │
                        │                  │ brian@bstinson.com>               │
                        ├──────────────────┼───────────────────────────────────┤
                        │17                │ Ralph Bean <rbean@redhat.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │15                │ Igor         Gnatenko         <‐  │
                        │                  │ ignatenkobrain@fedoraproject.org> │
                        ├──────────────────┼───────────────────────────────────┤
                        │15                │ Vibhor Verma <vibhcool@gmail.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │14                │ Justin W. Flory <git@jwf.io>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │13                │ Ghost-script                   <‐ │
                        │                  │ subho.prp@gmail.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │13                │ Martin Basti <mbasti@redhat.com>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │13                │ Mathieu         Bridon         <‐ │
                        │                  │ bochecha@fedoraproject.org>       │
                        ├──────────────────┼───────────────────────────────────┤
                        │11                │ Shengjing         Zhu          <‐ │
                        │                  │ zsj950618@gmail.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │9                 │ Michael         Watters        <‐ │
                        │                  │ michael.watters@dart.biz>         │
                        └──────────────────┴───────────────────────────────────┘

                        │9                 │ mprahl <mprahl@redhat.com>        │
                        ├──────────────────┼───────────────────────────────────┤
                        │8                 │ Lei Yang <yltt1234512@gmail.com>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │8                 │ Paul      W.      Frields      <‐ │
                        │                  │ stickster@gmail.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │7                 │ René            Genz           <‐ │
                        │                  │ liebundartig@freenet.de>          │
                        ├──────────────────┼───────────────────────────────────┤
                        │7                 │ Sergio    Durigan    Junior    <‐ │
                        │                  │ sergiodj@sergiodj.net>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │7                 │ zPlus <zplus@peers.community>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │6                 │ Michael Scherer <misc@redhat.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │6                 │ ymdatta <ymdatta@protonmail.com>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │5                 │ Fabio         Valentini        <‐ │
                        │                  │ decathorpe@gmail.com>             │
                        ├──────────────────┼───────────────────────────────────┤
                        │5                 │ Lukas Holecek <hluk@email.cz>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │5                 │ Mike McLean <mikem@redhat.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │5                 │ Oliver        Gutierrez        <‐ │
                        │                  │ ogutierrez@redhat.com>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │5                 │ Shaily <shaily15297@yahoo.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │5                 │ Till Maas <opensource@till.name>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │5                 │ jingjing <sanri.ok@163.com>       │
                        ├──────────────────┼───────────────────────────────────┤
                        │5                 │ vanzhiganov <vanzhiganov@ya.ru>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │5                 │ yangl1996 <yltt1234512@gmail.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │4                 │ Alex          Gleason          <‐ │
                        │                  │ alex@alexgleason.me>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │4                 │ Eric          Barbour          <‐ │
                        │                  │ ebarbour@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │4                 │ Maciej Lasyk <maciek@lasyk.info>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │4                 │ clime <clime@redhat.com>          │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Akanksha                       <‐ │
                        │                  │ akanksha_mishra01@yahoo.com>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Andrew       Engelbrecht       <‐ │
                        │                  │ andrew@engelbrecht.io>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Ankush Behl <cloudbehl@gmail.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Anthony         Lackey         <‐ │
                        │                  │ alackey96@gmail.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Chenxiong Qi <cqi@redhat.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Dhriti         Shikhar         <‐ │
                        │                  │ dhriti.shikhar.rokz@gmail.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Eric          Barbour          <‐ │
                        │                  │ emb4gu@virginia.edu>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ FeRD     (Frank     Dana)      <‐ │
                        │                  │ ferdnyc@gmail.com>                │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Jan Pokorný <jpokorny@redhat.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Jason         Tibbitts         <‐ │
                        │                  │ tibbs@math.uh.edu>                │
                        └──────────────────┴───────────────────────────────────┘

                        │3                 │ Kushal       Khandelwal        <‐ │
                        │                  │ kushal124@gmail.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Michal         Konečný         <‐ │
                        │                  │ mkonecny@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Miro Hrončok <miro@hroncok.cz>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Pedro Lima <pedro.lima@gmail.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Pierre-YvesChibon              <‐ │
                        │                  │ pingou@fedoraproject.org>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Ricky Elrod <ricky@elrod.me>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Ryan           Lerch           <‐ │
                        │                  │ rlerch@localhost.localdomain>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ Stefan Bühler <stbuehler@web.de>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ bill           auger           <‐ │
                        │                  │ mr.j.spam.me@gmail.com>           │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ cep <breathingcode@gmail.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ shivani <smshivani579@gmail.com>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ skrzepto <shims506@gmail.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │3                 │ tenstormavi                    <‐ │
                        │                  │ avi.avinash3008@gmail.com>        │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Akshay         Gaikwad         <‐ │
                        │                  │ akgaikwad001@gmail.com>           │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Anatoli         Babenia        <‐ │
                        │                  │ anatoli@rainforce.org>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Björn                     Persson │
                        │                  │ <Bjorn@Rombobjörn.se>             │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Carlos    Mogas   da   Silva   <‐ │
                        │                  │ r3pek@r3pek.org>                  │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Daniel Mach <dmach@redhat.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Fabian         Arrotin         <‐ │
                        │                  │ fabian.arrotin@arrfab.net>        │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Hervé Beraud <hberaud@redhat.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Kamil Páral <kparal@redhat.com>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Luis Guzman <ark@switnet.org>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ MR <mrx@mailinator.com>           │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Neha          Kandpal          <‐ │
                        │                  │ iec2015048@iiita.ac.in>           │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Nuno Maltez <nuno@cognitiva.com>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Ompragash <om.apsara@gmail.com>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Peter Oliver <git@mavit.org.uk>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Rahul          Bajaj           <‐ │
                        │                  │ rahulrb0509@gmail.com>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Richard          Marko         <‐ │
                        │                  │ rmarko@fedoraproject.org>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Simo Sorce <simo@redhat.com>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Stasiek       Michalski        <‐ │
                        │                  │ hellcp@opensuse.org>              │
                        └──────────────────┴───────────────────────────────────┘

                        │2                 │ Tim            Flink           <‐ │
                        │                  │ tflink@fedoraproject.org>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Tim        Landscheidt         <‐ │
                        │                  │ tim@tim-landscheidt.de>           │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Todd Zullinger <tmz@pobox.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ William     Moreno    Reyes    <‐ │
                        │                  │ williamjmorenor@gmail.com>        │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ Your           Name            <‐ │
                        │                  │ jlanda@fedoraproject.org>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ bruno <bruno@wolff.to>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ dhrish20 <dhrish20@gmail.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ hellcp <hellcp@opensuse.org>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ yadneshk <yadnesh45@gmail.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │2                 │ “AnjaliPardeshi”              <“‐ │
                        │                  │ anjalipardeshi92@gmail.com”>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Akanksha        Mishra         <‐ │
                        │                  │ akanksha_mishra01@yahoo.com>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Aleksandra  Fedorova (bookwar) <‐ │
                        │                  │ afedorova@mirantis.com>           │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Alexander        Scheel        <‐ │
                        │                  │ ascheel@redhat.com>               │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Alois Mahdal <amahdal@redhat.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Amol Kahat <akahat@redhat.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Anthony         Lackey         <‐ │
                        │                  │ alackey@localhost.localdomain>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Antoni   Segura    Puimedon    <‐ │
                        │                  │ celebdor@gmail.com>               │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Arti           Laddha          <‐ │
                        │                  │ artiladdha53@gmail.com>           │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Brian    (bex)    Exelbierd    <‐ │
                        │                  │ bex@pobox.com>                    │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Carl           George          <‐ │
                        │                  │ carl@george.computer>             │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Charelle        Collett        <‐ │
                        │                  │ ccollett@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ David Caro <dcaroest@redhat.com>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Devesh     Kumar     Singh     <‐ │
                        │                  │ deveshkusingh@gmail.com>          │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Eashan <eashankadam@gmail.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Felix           Yan            <‐ │
                        │                  │ felixonmars@users.sf.net>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Filip Valder <fvalder@redhat.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Frank      Dana     (FeRD)     <‐ │
                        │                  │ ferdnyc@gmail.com>                │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Haikel         Guemar          <‐ │
                        │                  │ hguemar@fedoraproject.org>        │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Hazel Smith <hazel@hazelesque.uk> │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Jeremy Cline <jcline@redhat.com>  │
                        └──────────────────┴───────────────────────────────────┘

                        │1                 │ Jingjing Shao <sanri.ok@163.com>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ John          Florian          <‐ │
                        │                  │ jflorian@doubledog.org>           │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Jun Aruga <jaruga@redhat.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Ken Dreyer <kdreyer@redhat.com>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Kunaal Jain <kunaalus@gmail.com>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Mary      Kate      Fain       <‐ │
                        │                  │ mk@marykatefain.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Mathew         Robinson        <‐ │
                        │                  │ mathew.robinson3114@gmail.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Michal Srb <michal@redhat.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Mohan Boddu <mboddu@redhat.com>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Nils Philippsen <nils@redhat.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Pavel         Raiskup          <‐ │
                        │                  │ praiskup@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Peter          Kolínek         <‐ │
                        │                  │ fedora@pessoft.com>               │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Petr         Šplíchal          <‐ │
                        │                  │ psplicha@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Randy          Barlow          <‐ │
                        │                  │ randy@electronsweatshop.com>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Robert Bost <rbost@redhat.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Romain DEP. <rom1dep@gmail.com>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Ryan Lerch <ryanlerch@gmail.com>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Sachin         Kamath          <‐ │
                        │                  │ sskamath96@gmail.com>             │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Snehal          Karale         <‐ │
                        │                  │ skarale@redhat.com>               │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Stanislav       Laznicka       <‐ │
                        │                  │ slaznick@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Stanislav      Ochotnicky      <‐ │
                        │                  │ sochotnicky@redhat.com>           │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Stephen       Gallagher        <‐ │
                        │                  │ sgallagh@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Tiago      M.      Vieira      <‐ │
                        │                  │ tiago@tvieira.com>                │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Till          Hofmann          <‐ │
                        │                  │ hofmann@kbsg.rwth-aachen.de>      │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Vadim         Rutkovsky        <‐ │
                        │                  │ vrutkovs@redhat.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Vyacheslav     Anzhiganov      <‐ │
                        │                  │ vanzhiganov@ya.ru>                │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ Yves           Martin          <‐ │
                        │                  │ ymartin1040@gmail.com>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ abhishek                       <‐ │
                        │                  │ abhishekarora12@gmail.com>        │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ abhishek        goswami        <‐ │
                        │                  │ abhishekg785@gmail.com>           │
                        └──────────────────┴───────────────────────────────────┘

                        │1                 │ alunux <fadlun.net@gmail.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ anar <anaradilovab@gmail.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ anatoly       techtonik        <‐ │
                        │                  │ techtonik@gmail.com>              │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ anshukira <aks.anshu03@gmail.com> │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ chocos10 <iec2015048@iiita.ac.in> │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ d3prof3t                       <‐ │
                        │                  │ saurabhpysharma@gmail.com>        │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ ishcherb <ishcherb@redhat.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ jcvicelli <jcvicelli@gmail.com>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ josef         radinger         <‐ │
                        │                  │ cheese@nosuchhost.net>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ midipix <writeonce@midipix.org>   │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ mrx@mailinator.com             <‐ │
                        │                  │ mrx@mailinator.com>               │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ pingou <pingou@fedoraproject.org> │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ prasad0896 <shendep@yahoo.co.in>  │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ rishika7000                    <‐ │
                        │                  │ rishika7000@gmail.com>            │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ ryanlerch <rlerch@redhat.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ sclark                         <‐ │
                        │                  │ simon.richard.clark@gmail.com>    │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ skrzepto <skrzepto@gmail.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ smit          thakkar          <‐ │
                        │                  │ smitthakkar96@gmail.com>          │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ smurfix <matthias@urlichs.de>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ vibhcool <vibhcool@gmail.com>     │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ vivekanand1101                 <‐ │
                        │                  │ vivekanand1101@gmail.com>         │
                        ├──────────────────┼───────────────────────────────────┤
                        │1                 │ waifu <heweyo6819@ualmail.com>    │
                        └──────────────────┴───────────────────────────────────┘

       This list is generated using

          git shortlog -s -n -e

       The old pagure logo has been created by Micah Denn <micah.denn@gmail.com>, the new one, as
       well  as  the entire version 2 of the user interface (using bootstrap) is the work of Ryan
       Lerch <rlerch@redhat.com> many thanks to them for their work and understanding during  the
       process.

RUNS HERE

   List of locations where Pagure is currently used
       Please  add  yourself here if you run a local version of Pagure. Please also describe what
       you are using it for.

                  ┌──┬──────────┬───────────────────────────────┬─────────────────────┐
                  │# │ Project  │ Site Name                     │ Used for            │
                  ├──┼──────────┼───────────────────────────────┼─────────────────────┤
                  │0 │ Fedorahttps://src.fedoraproject.org │ Development      of │
                  │  │          │                               │ Fedora        Linux │
                  │  │          │                               │ distribution        │
                  ├──┼──────────┼───────────────────────────────┼─────────────────────┤
                  │1 │ CentOShttps://git.centos.org        │ Development      of │
                  │  │          │                               │ CentOS        Linux │
                  │  │          │                               │ distribution        │
                  └──┴──────────┴───────────────────────────────┴─────────────────────┘

                  │2 │ Midipixhttps://dev.midipix.org       │ Development      of │
                  │  │          │                               │ Midipix and related │
                  │  │          │                               │ projects            │
                  ├──┼──────────┼───────────────────────────────┼─────────────────────┤
                  │3 │ Cool Bughttps://repo.coolbug.org      │ Development      of │
                  │  │          │                               │ personal projects   │
                  └──┴──────────┴───────────────────────────────┴─────────────────────┘

       This documentation is generated from the doc folder in the pagure's sources. Feel free  to
       report  issues  about  the  documentation  on  the  pagure  issue  tracker or even better,
       contribute to it!

       • IndexModule IndexSearch Page

AUTHOR

       Pierre-Yves Chibon <pingou@pingoured.fr>

COPYRIGHT

       2023, Red Hat Inc, Pierre-Yves Chibon <pingou@pingoured.fr>