[mirror] Command-line application for uploading a site to a git-pages server

Implement forge authorization.

Changed files
+32 -2
+19
README.md
··· 73 73 $ git-pages-cli https://example.org --server grebedoc.dev --password xyz --upload-dir ... 74 74 ``` 75 75 76 + ### Forge authorization 77 + 78 + Uploading a directory to a site on a wildcard domain (e.g. `https://<owner>.grebedoc.dev/<repo>`) requires the use of an access token with push permissions for the corresponding repository (`https://codeberg.org/<owner>/<repo>.git` in this case). 79 + 80 + To create such an access token on Forgejo: 81 + 1. Open _Settings_ > _Applications_ > _Access tokens_. 82 + 1. Expand _Select permissions_, pick _Read and write_ under _repository_. 83 + 1. Set _Token name_ to something informative (e.g. "git-pages publishing"). 84 + 1. Click _Generate token_. 85 + 1. The token will appear in a notification (a long string of hexadecimal numbers all on its own). 86 + 87 + To deploy using an access token: 88 + 89 + ```console 90 + $ git-pages-cli https://username.grebedoc.dev --token <token> --upload-dir ... 91 + ``` 92 + 93 + **Keep the access token safe and secure!** Anyone who has it will be able to change the data in any of your repositories. 94 + 76 95 77 96 Advanced usage 78 97 --------------
+13 -2
main.go
··· 18 18 ) 19 19 20 20 var passwordFlag = pflag.String("password", "", "password for DNS challenge authorization") 21 + var tokenFlag = pflag.String("token", "", "token for forge authorization") 21 22 var challengeFlag = pflag.Bool("challenge", false, "compute DNS challenge entry from password (output zone file record)") 22 23 var challengeBareFlag = pflag.Bool("challenge-bare", false, "compute DNS challenge entry from password (output bare TXT value)") 23 24 var uploadGitFlag = pflag.String("upload-git", "", "replace site with contents of specified git repository") ··· 103 104 return 104 105 } 105 106 107 + const usageExitCode = 125 108 + 106 109 func main() { 107 110 pflag.Parse() 108 111 if !singleOperation() || (!*versionFlag && len(pflag.Args()) != 1) { ··· 110 113 "Usage: %s <site-url> [--challenge|--upload-git url|--upload-dir path|--delete]\n", 111 114 os.Args[0], 112 115 ) 113 - os.Exit(125) 116 + os.Exit(usageExitCode) 114 117 } 115 118 116 119 if *versionFlag { ··· 118 121 os.Exit(0) 119 122 } 120 123 124 + if *passwordFlag != "" && *tokenFlag != "" { 125 + fmt.Fprintf(os.Stderr, "--password and --token are mutually exclusive") 126 + os.Exit(usageExitCode) 127 + } 128 + 121 129 var err error 122 130 siteURL, err := url.Parse(pflag.Args()[0]) 123 131 if err != nil { ··· 203 211 panic("no operation chosen") 204 212 } 205 213 request.Header.Add("User-Agent", versionInfo()) 206 - if *passwordFlag != "" { 214 + switch { 215 + case *passwordFlag != "": 207 216 request.Header.Add("Authorization", fmt.Sprintf("Pages %s", *passwordFlag)) 217 + case *tokenFlag != "": 218 + request.Header.Add("Forge-Authorization", fmt.Sprintf("token %s", *tokenFlag)) 208 219 } 209 220 if *serverFlag != "" { 210 221 // Send the request to `--server` host, but set the `Host:` header to the site host.