Co-authored-by: Justin Paul <justin@jpaul.me> Co-committed-by: Justin Paul <justin@jpaul.me>
This commit was merged in pull request #107.
This commit is contained in:
@@ -323,6 +323,88 @@ WSL, or Git Bash on Windows. Continues the `tasks-app` repo from Module 2.
|
|||||||
*direct the agent* to do the git work (add the remote, push, clone, fetch, pull) and you verify
|
*direct the agent* to do the git work (add the remote, push, clone, fetch, pull) and you verify
|
||||||
each result yourself. You don't type the git commands by hand.
|
each result yourself. You don't type the git commands by hand.
|
||||||
|
|
||||||
|
### Set up GitHub authentication (do this first)
|
||||||
|
|
||||||
|
This is the one part you do by hand in the web UI, and it's failure mode #1 above: the single most
|
||||||
|
common first-push wall. Set it up *before* Part A so the push just works. You have two paths; do
|
||||||
|
**one**. This lab walks the **PAT / HTTPS** path step by step on GitHub as the worked example,
|
||||||
|
because it's all in the browser and needs no command-line setup. SSH is the optional alternative,
|
||||||
|
linked below.
|
||||||
|
|
||||||
|
> **Other host?** These are GitHub's exact menu paths as the worked example. On GitLab, Bitbucket,
|
||||||
|
> Codeberg, or your own Forgejo/Gitea the *shape* is identical (see the "Getting a credential" callout
|
||||||
|
> in the lesson) but the menu names drift; find your host's "access tokens" or "SSH keys" settings.
|
||||||
|
|
||||||
|
**Path 1: Personal access token (PAT) over HTTPS.** Generate a token in GitHub's web UI, then paste
|
||||||
|
it once when Git asks for a password.
|
||||||
|
|
||||||
|
1. On GitHub, go to your avatar (top right) → **Settings** → **Developer settings** (bottom of the
|
||||||
|
left sidebar) → **Personal access tokens**. GitHub offers two token types:
|
||||||
|
|
||||||
|
- **Fine-grained tokens** (recommended): scoped to a single repository, with explicit permissions.
|
||||||
|
This lab uses fine-grained.
|
||||||
|
- **Tokens (classic)**: older, broader; access is controlled by a coarse `repo` scope that grants
|
||||||
|
all your repos at once.
|
||||||
|
|
||||||
|
Pick **Fine-grained tokens** → **Generate new token**.
|
||||||
|
|
||||||
|
2. Fill in the token:
|
||||||
|
|
||||||
|
- **Token name:** anything memorable, e.g. `tasks-app-push`.
|
||||||
|
- **Expiration:** pick a real expiry (30 to 90 days is fine for the lab). Tokens expire by design;
|
||||||
|
that's a rotation cost you accept for the convenience.
|
||||||
|
- **Repository access:** choose **Only select repositories** and select your `tasks-app` repo. If
|
||||||
|
you haven't created the empty remote yet (Part A step 1), come back and select it after, or
|
||||||
|
create the repo first and then make the token. The token only needs to *reach* a repo that
|
||||||
|
exists.
|
||||||
|
- **Permissions → Repository permissions → Contents:** set it to **Read and write**. This is the
|
||||||
|
write scope, and it is *the* gotcha: a token without it authenticates fine and then `403`s on
|
||||||
|
push (failure mode #1's scope trap). GitHub auto-adds **Metadata: Read** when you do this; leave
|
||||||
|
it.
|
||||||
|
|
||||||
|
3. Click **Generate token** and **copy the value immediately.** GitHub shows it exactly once. If you
|
||||||
|
lose it, you generate a new one rather than recover the old.
|
||||||
|
|
||||||
|
4. At the first push (Part A step 2), Git prompts for a **username** and **password**:
|
||||||
|
|
||||||
|
- **Username:** your GitHub username.
|
||||||
|
- **Password:** paste the **token** (not your GitHub account password; password auth over HTTPS
|
||||||
|
was removed years ago). Most terminals show *nothing* while you paste a secret; that's normal,
|
||||||
|
not a hang. Press Enter.
|
||||||
|
|
||||||
|
A **credential helper** caches it after the first success (`git config --global credential.helper`,
|
||||||
|
set to `osxkeychain` on macOS, `manager` on Windows, or `store`/`cache` on Linux), so you paste the
|
||||||
|
token *once*, not on every push.
|
||||||
|
|
||||||
|
> **Verify-before-publish:** GitHub's menu wording, token-type names, and the **Contents: Read and
|
||||||
|
> write** permission label drift. Re-confirm the path **Settings → Developer settings → Personal
|
||||||
|
> access tokens → Fine-grained tokens** and the Contents scope before relying on these exact names.
|
||||||
|
|
||||||
|
**Path 2: SSH key (optional alternative).** A key you add to your account skips passwords entirely.
|
||||||
|
It's more upfront setup (generate a keypair, load the ssh-agent, paste the *public* key into GitHub),
|
||||||
|
but then there's no token to scope, expire, or cache. Follow GitHub's official docs, in order:
|
||||||
|
|
||||||
|
- [Generating a new SSH key and adding it to the ssh-agent](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
|
||||||
|
- [Adding a new SSH key to your GitHub account](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)
|
||||||
|
- [Testing your SSH connection](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/testing-your-ssh-connection)
|
||||||
|
|
||||||
|
If you go SSH, use the **SSH** URL (`git@github.com:…`) when you create the remote in Part A, not the
|
||||||
|
HTTPS one.
|
||||||
|
|
||||||
|
**Which should you pick?**
|
||||||
|
|
||||||
|
| | **PAT / HTTPS** | **SSH key** |
|
||||||
|
|---|---|---|
|
||||||
|
| **Setup** | Fast, all in the web UI; nothing to install | More upfront: keygen, ssh-agent, add the public key |
|
||||||
|
| **After setup** | Credential helper caches the token; otherwise re-paste | No prompts ever; nothing to cache |
|
||||||
|
| **Network** | Port 443; sails through corporate proxies/firewalls | Port 22; sometimes blocked on locked-down networks |
|
||||||
|
| **Maintenance** | Expires; needs rotation; the write-scope `403` trap; shown once | No expiry by default; no scope to misconfigure |
|
||||||
|
| **Risk to manage** | A leaked token until it expires/is revoked | A private key + passphrase on your disk |
|
||||||
|
|
||||||
|
Short version: **PAT** is the faster start and the friendlier path behind a corporate firewall;
|
||||||
|
**SSH** is the lower-friction *long-term* setup once you're past the initial keygen. Either one
|
||||||
|
satisfies the lab. If you're unsure, do the PAT.
|
||||||
|
|
||||||
### Part A: Create the empty remote and push
|
### Part A: Create the empty remote and push
|
||||||
|
|
||||||
1. On your host's web UI, create a **new, empty** repository named `tasks-app`. Do **not** add a
|
1. On your host's web UI, create a **new, empty** repository named `tasks-app`. Do **not** add a
|
||||||
@@ -514,4 +596,9 @@ tables, and update the "as of" date when you do.
|
|||||||
- [ ] **Credential/token UI**: the "Getting a credential" callout names menu paths and the
|
- [ ] **Credential/token UI**: the "Getting a credential" callout names menu paths and the
|
||||||
write-scope label (`repo` / "read and write") generically; confirm the current wording and
|
write-scope label (`repo` / "read and write") generically; confirm the current wording and
|
||||||
scope name on the default-example host before publishing.
|
scope name on the default-example host before publishing.
|
||||||
|
- [ ] **GitHub PAT walkthrough** (lab "Set up GitHub authentication"): confirm the menu path
|
||||||
|
**Settings → Developer settings → Personal access tokens → Fine-grained tokens**, the two token
|
||||||
|
types (**fine-grained** vs **classic**/`repo`), and that the write scope is **Repository
|
||||||
|
permissions → Contents: Read and write** (with **Metadata: Read** auto-added). These are
|
||||||
|
volatile GitHub UI labels; also re-confirm the three linked SSH docs URLs still resolve.
|
||||||
- [ ] Update the comparison's **"as of" date** to the build date.
|
- [ ] Update the comparison's **"as of" date** to the build date.
|
||||||
|
|||||||
Reference in New Issue
Block a user