Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

219 linesCodeBlameRaw
1---
2title: The phone app
3description: g1t on Android and iOS, built with Expo. Highly experimental and barely working yet. Android first, downloaded from g1t.sh while it waits for Google Play.
4---
5
6The phone app is meant to be g1t on Android and iOS, with its own
7screens for what you do away from a desk: talking with your team in
8Chat, with notifications on your phone, and reviewing pull requests in
9Code. Everything else opens on the site, in your phone's browser.
10
11:::caution[Highly experimental]
12The phone app is early and barely works yet: expect missing screens,
13rough edges and things that break. For real work, use
14[the desktop app](/guides/desktop/) or g1t in your phone's browser.
15:::
16
17## Install it
18
19Android comes first. Get it from [g1t.sh/download](https://g1t.sh/download):
20the page opens on **Android** when you visit it on an Android phone, and
21[g1t.sh/download?platform=android](https://g1t.sh/download?platform=android)
22opens it from anywhere.
23
241. On your Android phone, choose **Download for Android**. On a computer,
25 scan the code beside it with the phone's camera instead.
262. Open the downloaded file. Android asks once to allow your browser to
27 install apps: allow it. If Play Protect warns about an unknown app,
28 choose **More details**, then **Install anyway**.
293. Open **g1t** and choose **Sign in with g1t**.
30
31Point at the file's name on the page to see its SHA-256, to check the file
32you have is the one g1t published. Like every g1t build during the alpha,
33the app isn't code-signed yet, which is why Android warns
34([unsigned during the alpha](/guides/desktop/#unsigned-during-the-alpha)).
35
36**Why a download, and not Google Play?** Google Play and the App Store
37publish a company's apps only once it is verified with a D-U-N-S number,
38and Flagon's is on its way. Until then the Android app is published on
39g1t.sh, as [the desktop app](/guides/desktop/) is. It moves
40into Google Play as soon as it can. iOS has no way in but the App Store,
41so it follows then.
42
43**Updates** reach the app by themselves: most arrive the next time you
44open it, with nothing to install. A change that needs a new install is a
45new release on the download page; installing it over the one you have
46keeps you signed in.
47
48The bar along the bottom is the site's phone bar:
49
50| Tab | What is on it |
51| --- | --- |
52| **Home** | Coming. Opens Home on the site meanwhile. |
53| **Chat** | Your starred conversations, channels and direct messages, with what is unread, moving live. See [Chat](#chat). |
54| **Notifications** | Coming. Opens your notifications on the site meanwhile; messages to you already arrive [on the phone](#notifications). |
55| **Code** | The workspace's repositories, each with its pull requests and issues. A pull request shows its description, checks, conversation and changed files, and you can approve it or ask for changes. An issue shows the pull requests made for it, and you can comment. Shown when you use Code in the workspace. |
56| **More** | Whether this phone gets notifications, your workspaces, how you signed in, and **Sign out**. |
57
58## Chat
59
60Chat on the phone is the site's Chat: the same conversations, as they
61happen.
62
63- **Conversations** show messages as the site draws them: bold, italic,
64 code, lists, quotes, tables and links, with `@mentions`, `#channels`
65 and `#123` references standing out. Messages by one person a few minutes
66 apart run together, and each day is marked.
67- **Live.** New messages, edits, deletions and reactions appear as they
68 happen, and the line above the box says who is typing. Unread counts in
69 the list and on the **Chat** tab move as messages arrive anywhere.
70- **Sending** shows your message at once. If it doesn't reach g1t, it
71 stays, marked **Not sent**: tap it to try again.
72- **Long-press a message** to react, reply in a thread, copy it, or edit
73 or delete your own. Tap a reaction to add yours or take it back.
74- **Threads** open from a message's replies, with the message they are
75 under at the top.
76- **⋯** on a conversation stars, mutes or leaves it.
77- **New message** (the pen at the top of Chat) messages a person, or a few
78 people together, or makes a channel. **Browse** at the
79 foot of the list joins public channels.
80
81A notification for a conversation you have open is not shown; one for
82another shows as a banner at the top of the screen.
83
84## Notifications
85
86The phone gets the same notifications as [browser push](/guides/notifications/#on-your-phone):
87messages to you, mentions and replies in threads you are in, under the
88same rules. Nothing comes while you are using
89g1t in a browser or in the app itself, and nothing in
90[Do not disturb](/guides/chat/#sounds-and-do-not-disturb). Tapping one
91opens the conversation or thread it is about.
92
93The app asks to notify you the first time you sign in. To change it
94later, use **More → Notifications on this phone**, or the phone's own
95settings for g1t, where Android lists the **Messages** channel. Signing
96out stops them on that phone.
97
98## Signing in
99
100**Sign in with g1t** opens g1t.sh in your phone's browser, where you sign
101in as usual (with your password, GitHub, two-factor) and approve the app.
102The browser sends you back to the app, signed in. The app never sees your
103password. This is [OAuth](/guides/authentication/#signing-in-with-oauth):
104the app is listed as **g1t for Android** or **g1t for iOS** in
105[Settings → Connected applications](https://g1t.sh/settings/applications),
106where **Change access** narrows what it can do and **Sign out** ends it at
107once.
108
109The approval page lists what the app asks for: reading your account,
110workspaces, repositories, checks and workflows, reading and writing
111issues, pull requests and notifications, and reading artifacts. Untick what you would rather it
112could not do.
113
114**Use an access token** signs in with a
115[personal access token](/guides/authentication/#access-tokens) you paste
116in instead. The token stays on your phone, in its keystore.
117
118The app asks for `chat:read` and `chat:write` too. They let it use
119Chat's routes and live connections on the site, and register for
120notifications, and nothing else there: the app's sign-in cannot open the
121site's pages as you.
122
123## Links
124
125A `g1t://` link opens the app, as it opens [the desktop app](/guides/desktop/#links):
126`g1t://acme/-/chat/dm/chn_1` is that conversation. The app shows the
127pages it has screens for:
128
129| Link | Opens |
130| --- | --- |
131| `g1t://<workspace>/-/chat`, `…/-/chat/<channel>`, `…/-/chat/dm/<id>` | Chat, or the conversation, in that workspace |
132| `g1t://<owner>/<repo>` | The repository |
133| `g1t://<owner>/<repo>/pull/<number>`, `…/issues/<number>` | The pull request or issue |
134
135Any other page opens on the site, in the browser.
136
137## Your own g1t
138
139The app works with a g1t you [run yourself](/guides/self-hosting/) as well
140as with g1t.sh. It talks to one g1t at a time, and opens on g1t.sh unless
141you point it elsewhere. Two ways to point it at yours:
142
143- **Scan its code.** Your g1t's download page, `<your g1t>/download`, has
144 a QR code under its platforms, **Use the phone app with** your g1t. Scan it with the phone's camera, or
145 open the page on the phone and choose **Open in the g1t app**. The app
146 asks **Use g1t.example.com?**, then signs you in there.
147- **Type its address.** On the sign-in screen, choose **Using your own
148 g1t? Sign in there** and enter the address you open it at in a browser,
149 such as `g1t.example.com`.
150
151Either way the app reads `<your g1t>/.well-known/g1t.json`, where your g1t
152says where its API is, so you never type that. A g1t from before the phone
153app has no such file: the app then takes the API to be `api.` in front of
154the site, and offers **Its API is at another address** if it is not.
155
156The sign-in screen then says **Signing in to g1t.example.com**, with
157**Change** and **Use g1t.sh**. Switching signs you out of the g1t you were
158on.
159
160| Your g1t | What to know |
161| --- | --- |
162| Reached by the phone | `PUBLIC_URL` and `API_URL` must be addresses the phone can open. `localhost` on a phone is the phone itself: use your computer's address on the network, or a domain. |
163| `https` | Store builds of the app open `https` addresses only, as Android requires. A development build also opens `http`, for a g1t on your own network. |
164| Notifications | Work with no setup: your g1t sends them through Expo's push service, as g1t.sh does. To keep notifications' words off Expo's, Google's and Apple's services, set `PHONE_PUSH=off` ([self-hosting](/guides/self-hosting/#the-phone-app)); the app then says your g1t sends no notifications, and Chat still updates while it is open. |
165| Older versions | A g1t from before the phone app does not let the app's sign-in into Chat. Upgrade it, or sign in with an access token that has **Use the website as you**. |
166
167## What's not there yet
168
169- **Google Play and the App Store**, once Flagon's D-U-N-S number
170 arrives ([above](#install-it)). Until then, Android from the download
171 page; iOS waits for the App Store.
172- **Home, Notifications and Artifacts** as tabs of their own.
173 Their pages open on the site meanwhile.
174- **Formatting in Code.** Descriptions and comments show their Markdown
175 as written; messages in Chat are formatted.
176- **Attachments and custom emoji.** Files in messages, and a
177 workspace's own `:emoji:`, show as their names.
178- **Replying from a notification**, without opening the app.
179- **https links.** `g1t.sh` addresses open the site in the browser, not
180 the app, until g1t.sh publishes the files Android and iOS check first.
181
182## For operators: building and releasing
183
184The app lives in `apps/mobile`: [Expo](https://expo.dev) with Expo
185Router, in TypeScript, sharing types with the site through
186`@g1t/contracts`. It builds with EAS Build. `apps/mobile/README.md` has
187the commands for running it on a phone and the first-time setup.
188
189| Build | Command | What it makes |
190| --- | --- | --- |
191| Development | `eas build --profile development --platform android` | An APK of `g1t (dev)` (`sh.g1t.app.dev`) that loads its code from your computer. |
192| Preview | `npm run build:android:apk -w @g1t/mobile` | An APK of `g1t` (`sh.g1t.app.preview`) to install on testers' phones. |
193| Production | `npm run build:android -w @g1t/mobile` | An Android App Bundle of `g1t` (`sh.g1t.app`) for Google Play. |
194
195The three install side by side. `eas submit --platform android` sends
196the latest production build to Google Play's internal testing track as a
197draft, once there is a Play account to send it to.
198
199### Releasing on g1t.sh/download
200
201Until the app is in Google Play, the `preview` build is the one people
202install, from g1t.sh/download. A release is a tag `mobile-v<version>`,
203where the version is `version` in `apps/mobile/app.config.ts`: push it,
204and the `Mobile release` workflow (`.g1t/workflows/mobile-release.yml`)
205has EAS build the APK, then publishes it to the `g1t-downloads` bucket
206at `g1t.sh/downloads/mobile/<version>/` and points `mobile/latest.json`
207at it, which the download page reads. `scripts/mobile-release.mjs` does
208the same by hand (`build`, `fetch`, `manifest`, `publish`).
209
210| Secret or variable | What it is |
211| --- | --- |
212| `EXPO_TOKEN` | An Expo access token with access to the g1t project, from expo.dev |
213| `CLOUDFLARE_API_TOKEN`, `CLOUDFLARE_ACCOUNT_ID` | As the deploy has them |
214
215Most changes need no release: `eas update --channel preview` in
216`apps/mobile` sends the app's new code to every installed copy of that
217version, which takes it the next time it opens. A release is for a change
218to the app's native side (a new native module, `app.config.ts`) or its
219`version`, which is also what decides which updates a copy takes.