{"id":32172339,"url":"https://github.com/dwyl/gogs","last_synced_at":"2025-10-21T18:34:41.614Z","repository":{"id":39711065,"uuid":"50670254","full_name":"dwyl/gogs","owner":"dwyl","description":"⚙️  Interface with a Gogs (Git Server) from any Elixir App","archived":false,"fork":false,"pushed_at":"2023-12-12T00:02:19.000Z","size":201,"stargazers_count":10,"open_issues_count":5,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-10-04T02:55:10.527Z","etag":null,"topics":["elixir","git","github","gogs","gogs-api","gogs-client","hex"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dwyl.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}},"created_at":"2016-01-29T15:15:11.000Z","updated_at":"2023-03-04T14:49:09.000Z","dependencies_parsed_at":"2023-11-13T20:26:38.314Z","dependency_job_id":"ffdddd2c-0e91-48a3-bafd-365bff6e3416","html_url":"https://github.com/dwyl/gogs","commit_stats":{"total_commits":133,"total_committers":6,"mean_commits":"22.166666666666668","dds":0.2857142857142857,"last_synced_commit":"3fe04a5f3476dcc47dfc85bd9ebdbe221bde1543"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/dwyl/gogs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwyl%2Fgogs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwyl%2Fgogs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwyl%2Fgogs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwyl%2Fgogs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dwyl","download_url":"https://codeload.github.com/dwyl/gogs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwyl%2Fgogs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280315396,"owners_count":26309890,"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","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["elixir","git","github","gogs","gogs-api","gogs-client","hex"],"created_at":"2025-10-21T18:34:38.087Z","updated_at":"2025-10-21T18:34:41.606Z","avatar_url":"https://github.com/dwyl.png","language":"Elixir","readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"https://user-images.githubusercontent.com/194400/162528448-5df0e9e8-a132-4644-b216-5107e0df0204.png\" alt=\"gogs elixir interface\"\u003e\n\nInterface with a **`Gogs`** instance from **`Elixir`**.\n\n[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/dwyl/gogs/Elixir%20CI?label=build\u0026style=flat-square)](https://github.com/dwyl/gogs/actions/workflows/ci.yml)\n[![codecov.io](https://img.shields.io/codecov/c/github/dwyl/gogs/main.svg?style=flat-square)](https://codecov.io/github/dwyl/gogs?branch=main)\n[![Hex.pm](https://img.shields.io/hexpm/v/gogs?color=brightgreen\u0026style=flat-square)](https://hex.pm/packages/gogs)\n[![Libraries.io dependency status](https://img.shields.io/librariesio/release/hex/gogs?logoColor=brightgreen\u0026style=flat-square)](https://libraries.io/hex/gogs)\n[![docs](https://img.shields.io/badge/docs-maintained-brightgreen?style=flat-square)](https://hexdocs.pm/gogs/api-reference.html)\n[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/dwyl/gogs/issues)\n[![HitCount](https://hits.dwyl.com/dwyl/gogs.svg)](https://hits.dwyl.com/dwyl/gogs)\n\u003c!-- uncomment when service is working ...\n[![Inline docs](https://inch-ci.org/github/dwyl/auth.svg?branch=master\u0026style=flat-square)](https://inch-ci.org/github/dwyl/auth)\n--\u003e\n\n\u003c/div\u003e\n\n# _Why?_ 💡\n\nWe needed an _easy_ way to interact \nwith our **`Gogs`** (GitHub Backup) **Server**\nfrom our **`Elixir/Phoenix`** App.\nThis package is that interface. \n\n\u003e **Note**: We were _briefly_ tempted \n\u003e to write this code _inside_ the Phoenix App \n\u003e that uses it, \n\u003e however we quickly realized\n\u003e that having it ***separate*** was better\n\u003e for ***testability/maintainability***.\n\u003e Having a _separate_ module enforces a\n\u003e [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns)\n\u003e with a strong \"API contract\".\n\u003e This way we know this package is well-tested,\n\u003e documented and maintained. \n\u003e And can be used and _extended independently_ \n\u003e of any `Elixir/Phoenix` app.\n\u003e The `Elixir/Phoenix` app can treat `gogs`\n\u003e as a logically separate/independent entity\n\u003e with a clear interface.\n\n# _What_? 📦\n\nA library for interacting with `gogs` (`git`)\nfrom `Elixir` apps. \u003cbr /\u003e\n\nHopefully this diagram explains \nhow we use the package:\n\n\u003cdiv align=\"center\"\u003e\n\n![Phoenix-Gogs-Infra-dagram](https://user-images.githubusercontent.com/194400/167098379-e06ee8ae-d652-4464-83d7-e209d442e9e2.png)\n\n\u003c/div\u003e\n\nFor the complete list of functions,\nplease see the docs: https://hexdocs.pm/gogs 📚 \n\n# Who? 👤 \n\nThis library is used by our (`Phoenix`) GitHub Backup App. \u003cbr /\u003e\nIf you find it helpful for your project,\nplease ⭐ on GitHub: \n[github.com/dwyl/gogs](https://github.com/dwyl/gogs)\n\n\n## _How_? 💻\n\nThere are a couple of steps to get this working in your project.\nIt should only take **`2 mins`** if you already have your\n**`Gogs` Server** _deployed_ (_or access to an existing instance_).\n\n\n\u003e If you want to read a **step-by-step complete beginner's guide**\n\u003e to getting **`gogs`** working in a **`Phoenix`** App,\n\u003e please see: \n\u003e [github.com/dwyl/**gogs-demo**](https://github.com/dwyl/gogs-demo)\n\n\n\u003cbr /\u003e\n\n## Install ⬇️\n\nInstall the package from [hex.pm](https://hex.pm/docs/publish), \nby adding `gogs` to the list of dependencies in your `mix.exs` file:\n\n```elixir\ndef deps do\n  [\n    {:gogs, \"~\u003e 1.0.2\"}\n  ]\nend\n```\n\nOnce you've saved the `mix.exs` file, \nrun: \n```sh\nmix deps.get\n```\n\n\u003cbr /\u003e\n\n## Config ⚙️\n\nIf you are writing tests for a function that relies on `gogs` (and you should!)\nthen you can add the following line to your `config/test.exs` file:\n\n```sh\nconfig :gogs, mock: true\n```\ne.g: [config/test.exs#L2-L4](https://github.com/dwyl/gogs/blob/f6d4658ae2a993aac3a76e812e915680964dfdb5/config/test.exs#L2-L4)\n\n\n\u003cbr /\u003e\n\n## _Setup_ 🔧\n\nFor `gogs` to work\nin your `Elixir/Phoenix` App,\nyou will need to have \na few environment variables defined.\n\nThere are **3 _required_** \nand **2 _optional_** variables.\nMake sure you read through the next section\nto determine if you _need_ the _optional_ ones.\n\n\n### _Required_ Environment Variables\n\n\u003e See: [`.env_sample`](https://github.com/dwyl/gogs/blob/main/.env_sample)\n\nThere are **3 _required_** environment variables:\n\n1. `GOGS_URL` - the domain where your Gogs Server is deployed,\n   without the protocol, e.g: `gogs-server.fly.dev`\n\n2. `GOGS_ACCESS_TOKEN` - the REST API Access Token \nSee: https://github.com/dwyl/gogs-server#connect-via-rest-api-https\n\n3. `GOGS_SSH_PRIVATE_KEY_PATH` - absolute path to the `id_rsa` file\n  on your `localhost` or `Phoenix` server instance.\n\n\u003e @SIMON: this last env var currently not being picked up.\n\u003e So it will just use `~/simon/id_rsa` \n\u003e You will need to add your `public` key \n\u003e to the Gogs instance for this to work on your `localhost`\n\u003e see:\n\u003e https://github.com/dwyl/gogs-server#add-ssh-key\n\n\n### _Optional_ Environment Variables\n\n#### `GOGS_SSH_PORT`\n\nIf your **`Gogs` Server** is configured \nwith a **_non-standard_ SSH port**, \nthen you need to define it:\n**`GOGS_SSH_PORT`** \u003cbr /\u003e\ne.g: `10022` for our \n`Gogs` Server deployed to Fly.io\n\nYou can easily discover the port by either visiting your\nGogs Server Config page: \u003cbr /\u003e\n`https://your-gogs-server.net/admin/config`\n\ne.g:\nhttps://gogs-server.fly.dev/admin/config\n\n\u003c!-- Move these screenshots to the gogs-server repo ssh section? --\u003e\n\n![gogs-ssh-port-config](https://user-images.githubusercontent.com/194400/167105374-ef36752f-80a7-4a77-8c78-2dda44a132f9.png)\n\nOr if you don't have admin access to the config page,\nsimply view the `ssh` clone link on a repo page,\ne.g: https://gogs-server.fly.dev/nelsonic/public-repo\n\n![gogs-ssh-port-example](https://user-images.githubusercontent.com/194400/167104890-31b06fa0-bd23-4ecb-b680-91c92398b0a7.png)\n\nIn our case the `GOGS_SSH_PORT` e.g: `10022`. \u003cbr /\u003e\nIf you don't set it, then `gogs` will assume TCP port **`22`**.\n\n#### `GIT_TEMP_DIR_PATH`\n\nIf you want to specify a directory where \nyou want to clone `git` repos to,\ncreate a `GIT_TEMP_DIR_PATH` environment variable.\ne.g:\n\n```sh\nexport GIT_TEMP_DIR_PATH=tmp\n```\n\n\u003e **Note**: the directory **must _already_ exist**.\n\u003e (it won't be created if it's not there ...)\n\n\u003cbr /\u003e\n\n## Usage\n\nIf you just want to _read_ \nthe contents of a file hosted on\na `Gogs` Server,\nwrite code similar to this:\n\n```elixir\norg_name = \"myorg\"\nrepo_name = \"public-repo\"\nfile_name = \"README.md\"\n{:ok, %HTTPoison.Response{ body: response_body}} = \n  Gogs.remote_read_raw(org_name, repo_name,file_name)\n# use the response_body (plaintext data)\n```\n\nThis is exactly the use-case presented in our demo app:\n[dwyl/**gogs-demo**#4-create-function](https://github.com/dwyl/gogs-demo#4-create-function-to-interact-with-gogs-repo)\n\n\n\n\u003cbr /\u003e\n\nHere's a more real-world scenario \nin 7 easy steps:\n\n### 1. _Create_ a New Repo on the Gogs Server\n\n```elixir\n# Define the params for the remote repository:\norg_name = \"myorg\"\nrepo_name = \"repo-name\"\nprivate = false # boolean\n# Create the repo!\nGogs.remote_repo_create(org_name, repo_name, private)\n```\n\n\u003e ⚠️ **WARNING**: there is currently no way \n\u003e to create an Organisation on the `Gogs` Server\n\u003e via `REST API` so the `org_name` \n\u003e _must_ already exists. \n\u003e e.g: https://gogs-server.fly.dev/myorg\n\u003e We will be figuring out a workaround shortly ...\n\u003e https://github.com/dwyl/gogs/issues/17\n\n\n### 2. _Clone_ the Repo\n\n```elixir\ngit_repo_url = Gogs.Helpers.remote_url_ssh(org_name, repo_name)\nGogs.clone(git_repo_url)\n```\n\n\u003e Provided you have setup the environment variables,\n\u003e and your `Elixir/Phoenix` App has write access to the filesystem,\n\u003e this should work without any issues.\n\u003e We haven't seen any in practice. \n\u003e But if you get stuck at this step,\n\u003e [open an issue](https://github.com/dwyl/gogs/issues)\n\n### 3. _Read_ the Contents of _Local_ (Cloned) File\n\nOnce you've cloned the `Git` Repo from the `Gogs` Server\nto the local filesystem of the `Elixir/Phoenix` App,\nyou can read any file inside it.\n\n```elixir\norg_name = \"myorg\"\nrepo_name = \"public-repo\"\nfile_name = \"README.md\"\n{:ok, text} == Gogs.local_file_read(org_name, repo_name, file_name)\n```\n\n### 4. _Write_ to a File\n\n```elixir\nfile_name = \"README.md\"\ntext = \"Your README.md text\"\nGogs.local_file_write_text(org_name, repo_name, file_name, text)\n```\n\nThis will create a new file if it doesn't already exist.\n\n### 5. _Commit_ Changes\n\n```elixir\n{:ok, msg} = Gogs.commit(org_name, repo_name, \n  %{message: \"your commit message\", full_name: \"Al Ex\", email: \"alex@dwyl.co\"})\n```\n\n### 6. _Push_ to `Gogs` Remote\n\n```elixir    \n# Push to Gogs Server this one is easy.\nGogs.push(org_name, repo_name)\n```\n\n### 7. _Confirm_ the File was Update on the Remote repo\n\n```elixir\n# Confirm the README.md was updated on the remote repo:\n{:ok, %HTTPoison.Response{ body: response_body}} = \n    Gogs.remote_read_raw(org_name, repo_name, file_name)\n\"Your README.md text\"\n```\n\n\n## Full Function Reference / Docs? 📖 \n\nRather than duplicate all the docs here, \nplease read the complete function reference, \non hexdocs: https://hexdocs.pm/gogs/Gogs.html\n\n\u003cbr /\u003e\n\n## Tests! \n\nBy default, the tests run with \"mocks\",\nthis means that: \u003cbr /\u003e\n1. Functional tests run faster (0.2 seconds)\n2. Tests that require filesystem access will run on GitHub CI.\n3. We know that functions are appropriately \n  [\"Test Doubled\"]\n  so that a downstream `Elixir/Phoenix` app \n  can run in `mock: true` and tests will be mocked (and thus _fast_!)\n\nTo alter this setting to run the tests _without_ mocks,\nsimply change the boolean from:\n\n```elixir\nconfig :gogs, mock: true\n```\n\nTo:\n\n```elixir\nconfig :gogs, mock: false\n```\n\nYou should still see the same output as all the functions should be tested.\n\n### Test Coverage\n\nWhen you run the command:\n\n```sh\nmix c\n```\n(an alias for `mix coveralls.html`) \u003cbr /\u003e\nYou will see output similar to the following:\n\n```sh\nFinished in 0.1 seconds (0.1s async, 0.00s sync)\n3 doctests, 27 tests, 0 failures\n\nRandomized with seed 715101\n----------------\nCOV    FILE                                        LINES RELEVANT   MISSED\n100.0% lib/git_mock.ex                                55        7        0\n100.0% lib/gogs.ex                                   212       41        0\n100.0% lib/helpers.ex                                131       17        0\n100.0% lib/http.ex                                   119       18        0\n100.0% lib/httpoison_mock.ex                         124       20        0\n[TOTAL] 100.0%\n----------------\n```\n\nIf you want to run the tests _without_ mocks (i.e. \"end-to-end\"),\nupdate the line in `config/test.exs`:\n\n```sh\nconfig :gogs, mock: false\n```\nWhen you run end-to-end tests with coverage tracking: \n\n```sh\nmix c\n```\n\nYou should see the same output:\n\n```sh\nFinished in 5.5 seconds (5.5s async, 0.00s sync)\n3 doctests, 27 tests, 0 failures\n\nRandomized with seed 388372\n----------------\nCOV    FILE                                        LINES RELEVANT   MISSED\n100.0% lib/git_mock.ex                                55        7        0\n100.0% lib/gogs.ex                                   212       41        0\n100.0% lib/helpers.ex                                131       17        0\n100.0% lib/http.ex                                   119       18        0\n100.0% lib/httpoison_mock.ex                         124       20        0\n[TOTAL] 100.0%\n----------------\n```\n\nThe only difference is the ***time*** it takes to run the test suite. \u003cbr /\u003e\nThe outcome (all tests passing and **100% coverage**) should be ***identical***.\n\nIf you add a feature to the package, \nplease ensure that the tests pass \nin both `mock: true` and `mock: false`\nso that we know it works in the _real_ world \nas well as in the simulated one. \n\n\u003cbr /\u003e\n\n## Roadmap\n\nWe are aiming to do a 1:1 feature map between GitHub and `Gogs`\nso that we can backup our entire organisation, all repos, issues, labels \u0026 PRs.\n\nWe aren't there yet\nand we might not be for some time.\nThe order in which we will be working \non fleshing out the features is:\n\n1. **Git Diff** - using the `Git` module to determine the changes made to a specific file\n  between two Git commits/hashes. This will allow us to visualize the changes made\n  and can therefore _derive_ the contents of a Pull Request \n  without having the PR feature exposed via the Gogs API.\n  See: https://github.com/dwyl/gogs/issues/27\n2. **Issues**: https://github.com/gogs/docs-api/tree/master/Issues\n  + **Comments** - this is the core content of issues. \n    We need to parse all the data and map it to the fields in `Gogs`.\n  + **Labels** - the primary metadata we use to categorize our issues, \n    see: https://github.com/dwyl/labels\n  + **Milestones** - used to _group_ issues into batches, e.g. a \"sprint\" or \"feature\".\n3. **Repo Stats**: Stars, watchers, forks etc.\n4. **_Your_ Feature Request** Here! \nSeriously, if you spot a gap in the list of available functions, \nsomething you want/need to use `Gogs` in any a more advanced/custom way,\nplease open an issue so we can discuss!\n\n\n\u003cbr /\u003e\n\n## I'm _Stuck!_ 🤷\n\nAs always, if anything is unclear\nor you are stuck getting this working,\nplease open an issue!\n[github.com/dwyl/gogs/issues](https://github.com/dwyl/gogs/issues/8)\nwe're here to help!\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003chr /\u003e\n\n# ⚠️ Disclaimer! ⚠️\n\nThis package is provided \"**as is**\". \nWe make ***no guarantee/warranty*** that it _works_. \u003cbr /\u003e\nWe _cannot_ be held responsible\nfor any undesirable effects of it's usage.\ne.g: if you use the [`Gogs.delete/1`](https://hexdocs.pm/gogs/Gogs.html#delete/1)\nit will _permanently/irrecoverably_ **`delete`** the repo. \nUse it with caution!\n\nWith the disclaimer out of the way,\nand your expectations clearly set,\nhere are the facts: \nWe are using this package in \"production\".\nWe rely on it daily and consider it \n[\"mission critical\"](https://en.wikipedia.org/wiki/Mission_critical).\nIt works for _us_ an and\nwe have made every effort to document, \ntest \u0026 _maintain_ it.\nIf you want to use it, go for it!\nBut please note that we cannot \"_support_\" your usage\nbeyond answering questions on GitHub.\nAnd unless you have a commercial agreement with \n[dwyl Ltd.]\n\nIf you spot anything that can be improved,\nplease open an \n[issue](https://github.com/dwyl/gogs/issues),\nwe're very happy to discuss! \n\n[![feedback welcome](https://img.shields.io/badge/feedback-welcome-brightgreen.svg?style=flat-square)](https://github.com/dwyl/gogs/issues)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwyl%2Fgogs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdwyl%2Fgogs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwyl%2Fgogs/lists"}