{"id":26711483,"url":"https://github.com/trac-hacks/trac-github","last_synced_at":"2025-04-13T19:50:56.948Z","repository":{"id":3275520,"uuid":"4315207","full_name":"trac-hacks/trac-github","owner":"trac-hacks","description":"Trac - GitHub integration","archived":false,"fork":false,"pushed_at":"2024-08-18T23:56:17.000Z","size":213,"stargazers_count":67,"open_issues_count":14,"forks_count":24,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-27T10:34:39.732Z","etag":null,"topics":["trac-plugin"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trac-hacks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-05-13T15:14:14.000Z","updated_at":"2024-09-09T13:36:13.000Z","dependencies_parsed_at":"2025-03-27T10:42:56.103Z","dependency_job_id":null,"html_url":"https://github.com/trac-hacks/trac-github","commit_stats":{"total_commits":162,"total_committers":11,"mean_commits":"14.727272727272727","dds":"0.47530864197530864","last_synced_commit":"004b382bb3c76c4d52a04aaaf57d00807e14f0d2"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trac-hacks%2Ftrac-github","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trac-hacks%2Ftrac-github/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trac-hacks%2Ftrac-github/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trac-hacks%2Ftrac-github/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trac-hacks","download_url":"https://codeload.github.com/trac-hacks/trac-github/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248773706,"owners_count":21159516,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["trac-plugin"],"created_at":"2025-03-27T10:28:41.498Z","updated_at":"2025-04-13T19:50:56.927Z","avatar_url":"https://github.com/trac-hacks.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Trac - GitHub integration\n=========================\n\nFeatures\n--------\n\nThis Trac plugin performs four functions:\n\n1. update the local git mirror used by Trac after each push to GitHub, and\n   notify the new changesets to Trac;\n2. authenticate users with their GitHub account;\n3. direct changeset TracLinks to GitHub's repository browser.\n4. sync GitHub teams to Trac permission groups\n\nThe notification of new changesets is strictly equivalent to the command\ndescribed in Trac's setup guide:\n\n    trac-admin TRAC_ENV changeset added ...\n\nEach feature is implemented in its own component and can be enabled or\ndisabled (almost) independently.\n\nRequirements\n------------\n\ntrac-github requires Trac \u003e= 0.12 and the git plugin.\n\nThe git plugin [is included](http://trac.edgewall.org/wiki/TracGit) in Trac \u003e=\n1.0 — you only have to enable it in `trac.ini`. For Trac 0.12 you have to\n[install it](http://trac-hacks.org/wiki/GitPlugin):\n\n    pip install git+https://github.com/hvr/trac-git-plugin.git\n\nThen install trac-github itself:\n\n    pip install trac-github\n\n`requests_oauthlib` is also a requirement if you plan to use `GitHubLoginModule`:\n\n    pip install requests_oauthlib\n\nSetup\n-----\n\n_Warning: the commands below are provided for illustrative purposes. You'll\nhave to adapt them to your setup._\n\n### Post-commit hook\n\n**`tracext.github.GitHubPostCommitHook`** implements a post-commit hook called\nby GitHub after each push.\n\nIt updates the git mirror used by Trac, triggers a cache update and notifies\ncomponents of the new changesets. Notifications are used by Trac's [commit\nticket updater](http://trac.edgewall.org/wiki/CommitTicketUpdater) and\n[notifications](http://trac.edgewall.org/wiki/TracNotification).\n\nFirst, you need a mirror of your GitHub repository, writable by the webserver,\nfor Trac's use:\n\n    cd /home/trac\n    git clone --mirror git://github.com/\u003cuser\u003e/\u003cproject\u003e.git\n    chown -R www-data:www-data \u003cproject\u003e.git\n\nEnsure that the user under which your web server runs can update the mirror:\n\n    su www-data\n    git --git-dir=/home/trac/\u003cproject\u003e.git remote update --prune\n\nNow edit your `trac.ini` as follows to configure both the git and the\ntrac-github plugins:\n\n    [components]\n    tracext.github.GitHubPostCommitHook = enabled\n    tracext.github.GitHubMixin = enabled\n    tracopt.ticket.commit_updater.* = enabled\n    tracopt.versioncontrol.git.* = enabled\n\n    [git]\n    trac_user_rlookup = enabled\n\n    [github]\n    repository = \u003cuser\u003e/\u003cproject\u003e\n\n    [trac]\n    repository_sync_per_request =   # Trac \u003c 1.2\n\n    [repositories]\n    .dir = /home/trac/\u003cproject\u003e.git\n    .type = git\n    .sync_per_request = false  # Trac \u003e= 1.2\n\nIn Trac 0.12, use `tracext.git.* = enabled` instead of\n`tracopt.versioncontrol.git.* = enabled`.\n\n`tracopt.ticket.commit_updater.*` activates the [commit ticket\nupdater](http://trac.edgewall.org/wiki/CommitTicketUpdater). It isn't\nrequired, but it's the most useful feature enabled by trac-github.\n\nThe author names that Trac caches are of the pattern\n`Full Name \u003cemail@domain.com\u003e`. The `trac_user_rlookup` option enables\nreverse mapping from email address to Trac user id. This is necessary\nfor commit ticket updater to function, and for `[trac]` options like\n[show_full_names](https://trac.edgewall.org/wiki/TracIni#trac-show_full_names-option)\nand\n[show_email_addresses](https://trac.edgewall.org/wiki/TracIni#trac-show_email_addresses-option)\nto be effective.\n\nReload the web server and your repository should appear in Trac.\n\nPerform an initial synchronization of the cache.\n\n    trac-admin $env repository resync \"(default)\"\n\nNote that `\"(default\")` will need to be replaced with the repository\nname if a named repository is used. See the\n[Trac documentation](https://trac.edgewall.org/wiki/TracRepositoryAdmin#ReposTracIni)\nfor more information.\n\nBrowse to the home page of your project in Trac and append `/github` to the\nURL. Append `/github/\u003creponame\u003e` if you have a named repository\n(see [multiple repositories](#multiple-repositories)). You should see the\nfollowing message:\n\n    Endpoint is ready to accept GitHub notifications.\n\nThis is the URL of the endpoint.\n\nIf you get a Trac error page saying \"No handler matched request to /github\"\ninstead, the plugin isn't installed properly. Make sure you've followed the\ninstallation instructions correctly and\n[search Trac's logs](https://trac.edgewall.org/wiki/TracTroubleshooting#ChecktheLogs)\nfor errors.\n\nNow go to your project's settings page on GitHub. In the \"Webhooks \u0026 Services\"\ntab, click \"Add webhook\". Put the URL of the endpoint in the \"Payload URL\"\nfield and set the \"Content type\" to `application/json`. Click \"Add webhook\".\n\nIf you click on the webhook you just created, at the bottom of the page, you\nshould see that a \"ping\" payload was successufully delivered to Trac\n\nOptionally, you can run additional actions every time GitHub triggers a webhook\nby placing a custom executable script at `\u003cproject\u003e.git/hooks/trac-github-update`.\n\n### Authentication\n\n**`tracext.github.GitHubLoginModule`** provides authentication through\nGitHub's OAuth API. It obtains users' names and email addresses after a\nsuccessful login if they're public and saves them in the preferences.\n\nTo use this module, your Trac instance must be served over HTTPS. This is a\nrequirement of the OAuth2 standard.\n\nGo to your accounts settings page on GitHub. From the *OAuth Application*\npage, click the *Developer applications* tab and *Register new application*.\nFor the \"Authorization callback URL\", put the URL of the homepage of your\nproject in Trac, starting with `https://`, and append `/github/oauth`.\nIn other words, this is the URL of the endpoint you used above plus `/oauth`\nThen click *Register application*.\n\nYou're redirected to your newly created application's page, which provides a\nClient ID and a Client Secret.\n\nNow edit edit `trac.ini` as follows:\n\n    [components]\n    trac.web.auth.LoginModule = disabled\n    tracext.github.GitHubLoginModule = enabled\n\n    [github]\n    client_id = \u003cyour Client ID\u003e\n    client_secret = \u003cyour Client Secret\u003e\n\nThis example disables `trac.web.auth.LoginModule`. Otherwise different users\ncould authenticate with the same username through different systems!\n\nIf it's impractical to set the Client ID and Client Secret in the Trac\nconfiguration file, you have some alternatives:\n\n- If `client_secret` matches `[A-Z_]+` (uppercase only), trac-github will use\n  the content of the corresponding environment variable as client secret.\n- If `client_secret` starts with '/' or './', trac-github will interpret it as\n  a file name and use the contents of that file as client secret.\n- If `client_secret` is anything else, trac-github will use it as is.\n\nBy default the preferences will use the public email address of the\nauthenticated GitHub user. If the public email address is not set, the field\nwill be empty. If the email address is important for your Trac installation\n(for example for notifications), the `request_email` option can be set to\nalways request access to all email addresses from GitHub. The primary address\nwill be stored in the preferences on the first login.\n\n    [github]\n    request_email = true\n    preferred_email_domain = example.org\n\nif specified, the first address matching the optional `preferred_email_domain`\nwill be used instead of the primary address.\n\nNote that the Trac mail address will only be initialized on the first login.\nUsers can still change or remove the email address from their Trac account.\n\n### Browser\n\n**`tracext.github.GitHubBrowser`** redirects changeset TracLinks to\nthe GitHub repositor browser. It requires the post-commit hook.\n\nTo enable it, edit `trac.ini` as follows:\n\n    [components]\n    trac.versioncontrol.web_ui.browser.BrowserModule = disabled\n    trac.versioncontrol.web_ui.changeset.ChangesetModule = disabled\n    trac.versioncontrol.web_ui.log.LogModule = disabled\n    tracext.github.GitHubBrowser = enabled\n    tracext.github.GitHubMixin = enabled\n\nSince it replaces standard URLs of Trac, you must disable three components in\n`trac.versioncontrol.web_ui`, as shown above.\n\nWith the `BROWSER_MODULE` disabled the `BROWSER_VIEW` and `FILE_VIEW` permissions will no longer be available. The permissions are checked when rendering files in the timeline, when `[timeline]` `changeset_show_files` is non-zero. Enabling the permission policy will make the list of files visible in the timeline for users that possess `CHANGESET_VIEW`.\n\nAdd the permission policy before `DefaultPermissionsPolicy`. It is usually correct to make it the first entry in the list.\n\nThe following will be correct for a Trac 1.2 installation that had the default value for `permission_policies`.\n\n    [trac]\n    permission_policies = GitHubPolicy, ReadonlyWikiPolicy, DefaultPermissionPolicy, LegacyAttachmentPolicy\n\n### Group Synchronization\n\nGitHub teams can be synced to Trac permission groups using\n**`tracext.github.GitHubGroupsProvider`**. It uses a dedicated GitHub user and\ntheir personal access token to synchronize group memberships. Note that this\nuser must have permission to read all your organization's teams. Additionally,\nthis module implements a Webhook endpoint to keep the groups synchronized at\nall times.\n\nRegister a new user for the synchronization or re-use an existing bot user.\nMake sure the bot user has owner privileges for your organization. Go to\n*Settings* \u003e *Developer settings* \u003e *Personal access tokens* and click\n*Generate a new token*. Make sure `read:org` under `admin:org` is checked and\nsubmit. Copy the displayed hex string.\n\nNow edit edit `trac.ini` as follows:\n\n    [components]\n    tracext.github.GitHubGroupsProvider = enabled\n    tracext.github.GitHubMixin = enabled\n\n    [github]\n\torganization = \u003cyour organization name\u003e\n\tusername = \u003cyour sync user's username\u003e\n\taccess_token = \u003cpaste the generated access token\u003e\n\nThis should give you an initial working synchronization of your organization's\nteams, but no automatic update. Because the cache does not expire, restarting\ntrac is your only option to force a resync. If the synchronization does not\nwork as expected, enable debug logging in Trac and check the logfile.\n\nNext, you should configure a Webhook to keep your groups up to date. Browse to\nthe home page of your project in Trac and append `/github-groups` to the URL.\nYou should see the following message:\n\n    Endpoint is ready to accept GitHub Organization membership notifications.\n\nThis is the URL of the endpoint.\n\nLog in as an organization owner and find the *Webhooks* panel in the\norganization's settings. Add a new webhook and use the endpoint URL in the\n*Payload URL* field. Use `application/json` as *Content type*. Leave the secret\nempty for now, and select *Membership* from the list of individual events.\nDisable the *Push* event, since this endpoint will not handle it. Add the\nwebhook, open it and check the list of recent deliveries. It should have sent\na successful ping event.\n\nFinally, you should secure your webhook. Generate a random shared secret, for\nexample using `/dev/urandom` and a hash algorithm:\n\n    dd if=/dev/urandom of=/dev/stdout bs=16 count=16 | openssl dgst -sha256\n\nCopy the secret, edit `trac.ini` and add\n\n    [github]\n\twebhook_secret = \u003cpaste the generated secret\u003e\n\nGo to your webook's settings on GitHub again and paste the secret in the\n*Secret* field. After saving, select the ping event from the recent deliveries\nlist and click *Redeliver* to make sure the shared secret works.\n\nThe synchronized groups will be named `github-${orgname}-${team_slug}`, e.g.\nfor the *extraordinary league* team of the *people* organization, the group in\nTrac will be named `github-people-extraordinary-league`.\n\nAn additional `github-${orgname}` group will contain all members of all teams\nin your organization. Note that members of your organization that are not part\nof a team will not be part of this group. This limitation is necessary because\nGitHub does not (yet) provide a notification mechanism for changes in\norganization membership.\n\nIf you do not want to store the API secrets for `access_token` and\n`webhook_secret` in trac.ini, you can use the same alternatives as for\n`client_id` and `client_secret` documented [above](#authentication).\n\n\nAdvanced setup\n--------------\n\n### Branches\n\nBy default, trac-github notifies all commits to Trac. But you may not wish\nto trigger notifications for commits on experimental branches until they're\nmerged, for example.\n\nYou can configure trac-github to only notify commits on some branches:\n\n    [github]\n    branches = master\n\nYou can provide more than one branch name, and you can use\n[shell-style wildcards](https://docs.python.org/2.7/library/fnmatch.html):\n\n    [github]\n    branches = master stable/*\n\nThis option also restricts which branches are shown in the timeline.\n\nBesides, trac-github uses relies on the 'distinct' flag set by GitHub to\nprevent duplicate notifications when you merge branches.\n\n### Multiple repositories\n\nIf you have multiple repositories, you must tell Trac how they're called on\nGitHub:\n\n    [github]\n    repository = \u003cuser\u003e/\u003cproject\u003e               # default repository\n    \u003creponame\u003e.repository = \u003cuser\u003e/\u003cproject\u003e    # for each extra repository\n    \u003creponame\u003e.branches = \u003cbranches\u003e            # optional\n\nWhen you configure the webhook URLs, append the name used by Trac to identify\nthe repository:\n\n    http://\u003ctrac.example.com\u003e/github/\u003creponame\u003e\n\n### Private repositories\n\nIf you're deploying trac-github on a private Trac instance to manage private\nrepositories, you have to take a few extra steps to allow Trac to pull changes\nfrom GitHub. The trick is to have Trac authenticate with a SSH key referenced\nas a deployment key on GitHub.\n\nAll the commands shown below must be run by the webserver's user, eg www-data:\n\n    $ su www-data\n\nGenerate a dedicated SSH key with an empty passphrase and obtain the public\nkey:\n\n    $ ssh-keygen -f ~/.ssh/id_rsa_trac\n    $ cat ~/.ssh/id_rsa_trac.pub\n\nMake sure you've obtained the public key (`.pub`). It should begin with\n`ssh-rsa`. If you're seeing an armored blob of data, it's the private key!\n\nGo to your project's settings page on GitHub. In the Deploy Keys tab, add the\npublic key.\n\nEdit the SSH configuration for the `www-data` user:\n\n    $ vi ~/.ssh/config\n\nAppend the following lines:\n\n    Host github-trac\n    Hostname github.com\n    IdentityFile ~/.ssh/id_rsa_trac\n\nEdit the git configuration for the repository:\n\n    $ cd /home/trac/\u003cproject\u003e.git\n    $ vi config\n\nReplace `github.com` in the `url` parameter by the `Host` value you've added\nto the SSH configuration:\n\n    url = git@github-trac:\u003cuser\u003e/\u003cproject\u003e.git\n\nMake sure the authentication works:\n\n    $ git remote update --prune\n\nSince GitHub doesn't allow reusing SSH keys across repositories, you have to\ngenerate a new key and pick a new `Host` value for each new repository.\n\nDevelopment\n-----------\n\nIn a [virtualenv](https://virtualenv.pypa.io/en/stable/), install the \nrequirements:\n\n    pip install trac\n    pip install coverage      # if you want to run the tests under coverage\n    pip install -e .\n\nor, instead of `pip install trac`:\n\n    pip install trac==0.12.7\n    pip install -e git+https://github.com/hvr/trac-git-plugin.git\n\n*The version of PyGIT bundled with `trac-git-plugin` doesn't work with\nthe `git` binary shipped with OS X. To fix it, in the virtualenv, edit\n`src/tracgit/tracext/git/PyGIT.py` and replace `_, _, version =\nv.strip().split()` with `version = v.strip().split()[2]`.*\n\nRun the tests with:\n\n    ./runtests.py\n\nDisplay Trac's log during the tests with:\n\n    ./runtests.py --with-trac-log\n\nRun the tests under coverage with:\n\n    coverage erase\n    ./runtests.py --with-coverage\n    coverage html\n\nIf you put a breakpoint in the test suite, you can interact with Trac's web\ninterface at [http://localhost:8765/](http://localhost:8765/) and with the git\nrepositories through the command line.\n\nRunning `tracd` ([TracStandalone](https://trac.edgewall.org/wiki/TracStandalone)) \nis the most convenient way to develop Trac from your workstation. Your local \ninstance of `tracd` can be exposed to the internet using\n[ngrok](https://ngrok.com/). Download, extract and run `ngrok`:\n\n    unzip ngrok-*.zip\n    ngrok http 8000 --log ngrok.log\n\nThe `ngrok` window will display a forwarding URL, for example:\n\n    Forwarding                    https://abd75d3e.ngrok.io -\u003e localhost:8000\n\nThe URL will be used for configuring the webhook and will change \neach time you restart ngrok. See the\n[ngrok docs](https://ngrok.com/docs) for additional configuration options.\n\nRun `tracd` on the port you specified to `ngrok`:\n\n    tracd -r -s -p 8000 /path/to/trac/env\n\nComplete the standard configuration steps in [setup](#setup). See the\n[Trac docs](https://trac.edgewall.org/wiki/TracDev/DevelopmentEnvironmentSetup)\nfor additional information on setting up a Trac development environment.\n\n\nRelease Steps\n-------------\n\nYou need to be an owner of the \n[package on PyPI](https://pypi.python.org/pypi/trac-github) to create a release.\nThe steps assume you've configured a \n[.pypirc file](https://packaging.python.org/distributing/#create-an-account).\n\n1. Update the [changelog](#changelog).\n2. Set `tag_build = ` in \n [setup.cfg](https://github.com/trac-hacks/trac-github/blob/master/setup.cfg)\n3. Create the release:\n\n    ```\n    $ virtualenv pve\n    $ . pve/bin/activate\n    $ pip install -U pip wheel setuptools twine\n    $ git clone https://github.com/trac-hacks/trac-github.git\n    $ cd trac-github\n    $ git tag \u003cversion\u003e\n    $ git push --tags\n    $ rm -r dist  # if reusing virtualenv, but using a new virtualenv is advised\n    $ python setup.py sdist bdist_wheel\n    $ twine upload dist/*.tar.gz dist/*.whl\n    ```\n    \nKnown issues\n------------\n\nOnce in a while, a notification doesn't appear in Trac.\n\nUsually, that happens when Trac fails to find the commit that triggered the\nnotification, even though it just synchronized the git repository with GitHub.\n\nYou can confirm that in your webhook's configuration page on GitHub. Scroll\ndown to \"Recent Deliveries\" and look at the delivery that failed. In the\n\"Response\" tab, you should see a response body such as:\n\n    Running hook on (default)\n    * Updating clone\n    * Synchronizing with clone\n    * Unknown commit ...\n\nSimply click \"Redeliver\". Then missing notification should appear in Trac and\nthe response body should change to:\n\n    Running hook on (default)\n    * Updating clone\n    * Synchronizing with clone\n    * Adding commit ...\n\nThis problem isn't well understood. It may be related to Trac's access layer\nfor git repositories. If you have an idea to fix it, please submit a patch!\n\nChangelog\n---------\n\n### 2.4 (not yet released)\n\n* Fix improperly configured namespace package. (#131)\n* Add configuration option for path prefix of login and logout. (#127)\n* Add `GitHubPolicy` permission policy to make `[timeline]`\n  `changeset_show_file` option work correctly. (#126)\n\n### 2.3\n\n* Support webhook signature verification for post commit hooks. (#114)\n* Allow passing a GitHub push webhook payload to a custom script per repository\n  that will receive GitHub's JSON on stdin for further postprocessing. (#114)\n* Improve interaction with both GitHub and non-GitHub repositories on a single\n  instance by delegating /changeset to the original ChangesetModule if enabled\n  and the GitHub module did not match. (#110)\n* Optionally request access to non-public email addresses from GitHub and allow\n  selection of an address by specifying a preferred domain. (#105)\n* Support synchronizing GitHub teams to Trac permission groups. (#104)\n\n### 2.2\n\n* CSRF security fix: add verification of OAuth state parameter.\n\n### 2.1.5\n\n* Support reading the GitHub OAuth secret from a file.\n* Trap `MissingTokenError` and add a warning.\n\n### 2.1.4\n\n* Make `requests-oauthlib` a requirement for `GitHubLoginModule`.\n* Improve description of functionality provided by plugin.\n\n### 2.1.3\n\n* Fix GitHub login failure with recent versions of oauthlib.\n* Fix logout after GitHub login on Trac \u003e= 1.0.2.\n* Update configuration example to reflect Trac's current best practice.\n* Move the project to the trac-hacks organization on GitHub.\n\n### 2.1.2\n\n* Make `tracext` a namespace package to support installation as an egg.\n* Improve responses when there's no repository at a requests's target URL.\n\n### 2.1.1\n\n* Fix GitHub login failure when a user has no email on GitHub.\n\n### 2.1\n\n* Add support for GitHub login.\n\n### 2.0\n\n* Adapt to GitHub's new webhooks.\n\nWhen you upgrade from 1.x, you must change your webhooks settings on GitHub to\nuse the application/vnd.github.v3+json format.\n\n### 1.2\n\n* Add support for cached repositories.\n\n### 1.1\n\n* Add support for multiple repositories.\n* Add an option to restrict notifications to some branches.\n* Try to avoid duplicate notifications (GitHub doesn't document the payload).\n* Use GitHub's generic webhook URLs.\n* Use a git mirror instead of a bare clone.\n\n### 1.0\n\n* Public release.\n\nLicense\n-------\n\nThis plugin is released under the BSD license.\n\nIt was initially written for [Django's Trac](https://code.djangoproject.com/).\nProminent users include [jQuery Trac](https://bugs.jquery.com), [jQuery UI\nTrac](https://bugs.jqueryui.com) and [MacPorts\nTrac](https://trac.macports.org).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrac-hacks%2Ftrac-github","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrac-hacks%2Ftrac-github","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrac-hacks%2Ftrac-github/lists"}