Provided by: pagure-doc_5.11.3+dfsg-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-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  and  create-fork
       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 custom-gitolite.

   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
       custom-gitolite).

       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 usage/theming

       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!

       • genindex

       • modindex

       • search

AUTHOR

       Pierre-Yves Chibon <pingou@pingoured.fr>

COPYRIGHT

       2020, Red Hat Inc, Pierre-Yves Chibon <pingou@pingoured.fr>