Compare commits

...

13 Commits
v0.0.3 ... main

Author SHA1 Message Date
Simon Gregor Ebner
711845d6be fix typo 2025-03-21 10:44:08 +01:00
Simon Gregor Ebner
d4e3b4bd88 add example docker-compose file 2025-03-21 10:42:12 +01:00
4267eb2661 added comment regarding pushing docker image 2025-03-12 17:43:39 +01:00
02abc7bcde bump version to 0.0.8 2025-03-12 17:32:31 +01:00
ec8227b98d improve path handling if path query parameters are present 2025-03-12 17:31:13 +01:00
02fae34477 update readme 2025-03-03 15:17:45 +01:00
7f2f378741 fix bug 2025-03-03 14:45:47 +01:00
0842be001b add option to either use fixed org repo or use github style nameing 2025-03-03 14:37:28 +01:00
28b9ac94f5 bump version 2025-03-03 13:37:46 +01:00
94dd5396ad add error log 2025-03-03 13:37:24 +01:00
f8b70e8cb9 change way default repo is called - second part fixed 2025-03-03 13:32:05 +01:00
f88e09b481 bump version 2025-03-03 13:04:25 +01:00
411bc54f6b change way default repo is called 2025-03-03 13:04:06 +01:00
5 changed files with 82 additions and 29 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
caddy
Caddyfile
Caddyfile
Caddyfile_gitea-test.psi.ch

View File

@ -1,6 +1,6 @@
FROM caddy:builder-alpine AS builder
RUN xcaddy build --with github.com/simongregorebner/gitea-pages@v0.0.3
RUN xcaddy build --with github.com/simongregorebner/gitea-pages@v0.0.8
FROM alpine

View File

@ -17,6 +17,12 @@ In __simple__ mode no special DNS setup is required and the access to the hosted
__http(s)://<your-server-hostname>/<organization>/<repository>__
To create a pages site, just
1. Create a `gitea-pages` branch in any repository of an organization
2. Put your content in this branch. (eg index.html) and push the branch
After the push the content will be available at: http(s)://<your-server-hostname>/<organization>/<repository>
## Classic Mode
In __classic__ mode the access to the pages goes according to these two patterns:
@ -27,10 +33,26 @@ or
__http(s)://<organization>.<your-server-hostname>__
The latter url scheme with serves the content of the repo named __<organization>.gitea-pages__ of the organization (with default settings).
The latter url scheme with serves the content of the repo named __gitea-pages__ of the organization (with default settings, however you can also set it to github like convention or __<organization>.<repository_suffix>__ ).
In this mode you can create pages content like this:
1. Create a `gitea-pages` repo in any organization
2. Create a `gitea-pages` branch in this `gitea-pages` repository
3. Put your content in this branch. (eg index.html)
Your content will now be available on https://<organization>.<your-server-domain>/index.html
Beside this you can simply create a `gitea-pages` branch in any repository of the organization and push it to the gitea server.
These pages are then available at: https://<organization>.<your-server-domain>/
Classic mode requires that you setup a _wildcard CNAME_ in DNS for your gitea pages host (see below for more details). You also need a _wildcard HTTPS_ certificate if you want to run with HTTPS.
# Usage
To run the server in __simple__ mode you need a minimal configuration (filename _Caddyfile_) like this (replace _your-gitea-server_ and _gitea_access_token_):
@ -89,7 +111,8 @@ log {
| server | The URL of your Gitea server. |
| token | Your access token for the Gitea API. This token is used to authenticate requests made to the Gitea server.|
| pages_branch | The branch in your repository that contains the static files for your website or documentation. By default, this would be the branch "gitea-pages" |
| postfix_pages_repository | The (domain) postfix used for the pages repository. (This could be the domain where your site will be accessible, such as "gitea.io".) |
| pages_repository | The default repository of an organization |
| postfix_pages_repository | The (domain) postfix used for the pages repository. __This setting is only used if pages_repository is not set!__ (This could be the domain where your site will be accessible, such as "gitea.io".) |
| url_scheme | The URL scheme to use for the pages. "simple" or "classic |
@ -139,6 +162,7 @@ docker build --platform=linux/amd64 -t gitea-pages .
# example build image for this github user
docker build --platform=linux/amd64 -t ghcr.io/simongregorebner/gitea-pages:0.0.1 .
docker push ghcr.io/simongregorebner/gitea-pages:0.0.1
```
## Testing

12
docker-compose.yml Normal file
View File

@ -0,0 +1,12 @@
services:
server:
image: ghcr.io/simongregorebner/gitea-pages:0.0.8
container_name: gitea-pages
restart: always
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "8080:8080/tcp"

View File

@ -6,6 +6,7 @@ import (
"io/fs"
"mime"
"net/http"
"net/url"
"strings"
"code.gitea.io/sdk/gitea"
@ -34,6 +35,7 @@ type GiteaPagesModule struct {
Server string `json:"server,omitempty"`
Token string `json:"token,omitempty"`
PagesBranch string `json:"pages_branch,omitempty"`
PagesRepository string `json:"pages_repository,omitempty"`
PostfixPagesRepository string `json:"postfix_pages_repository,omitempty"`
URLScheme string `json:"url_scheme,omitempty"`
}
@ -65,6 +67,8 @@ func (module *GiteaPagesModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error
d.Args(&module.Token)
case "pages_branch":
d.Args(&module.PagesBranch)
case "pages_repository":
d.Args(&module.PagesRepository)
case "postfix_pages_repository":
d.Args(&module.PostfixPagesRepository)
case "url_scheme":
@ -76,8 +80,10 @@ func (module *GiteaPagesModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error
if module.PagesBranch == "" {
module.PagesBranch = "gitea-pages"
}
if module.PostfixPagesRepository == "" {
module.PostfixPagesRepository = "gitea-pages"
if module.PagesRepository == "" {
if module.PostfixPagesRepository == "" {
module.PostfixPagesRepository = "gitea-pages"
}
}
if module.URLScheme == "" {
@ -98,12 +104,18 @@ func (module *GiteaPagesModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error
func (module GiteaPagesModule) ServeHTTP(writer http.ResponseWriter, request *http.Request, _ caddyhttp.Handler) error {
var organization, repository, path string
// the path might have url query parameters e.g. "?h=vpn" - this need to be stripped of
parsedUrl, _ := url.Parse(request.URL.Path)
parsedUrl.RawQuery = "" // Clear the query parameters
path = parsedUrl.String()
if module.URLScheme == "simple" {
// "Simple" URL case - we expect the organization and repository in the URL
// The URL/path looks like http(s)://<giteaserver>[:<port>]/<organization>/<repository>[/<filepath>]
// Remove a potential "/" prefix and trailing "/" - then split up the path
parts := strings.Split(strings.TrimSuffix(strings.TrimPrefix(request.URL.Path, "/"), "/"), "/")
parts := strings.Split(strings.TrimSuffix(strings.TrimPrefix(path, "/"), "/"), "/")
length := len(parts)
if length <= 1 {
@ -125,14 +137,19 @@ func (module GiteaPagesModule) ServeHTTP(writer http.ResponseWriter, request *ht
organization = strings.Split(request.Host, ".")[0]
// Remove a potential "/" prefix and trailing "/" - then split up the path
path = strings.TrimSuffix(strings.TrimPrefix(request.URL.Path, "/"), "/")
path = strings.TrimSuffix(strings.TrimPrefix(path, "/"), "/")
if path == "" {
// Case http(s)://<organization>.<giteaserver>[:<port>]
// (Try to) Use of the pages repository in the specified organization
// We use github.com conventions: <organization>.github.io
repository = organization + "." + module.PostfixPagesRepository
// Determine name of the default repository for organization based on settings
if module.PagesRepository != "" {
repository = module.PagesRepository
} else {
// We use github.com conventions: <organization>.github.io
repository = organization + "." + module.PostfixPagesRepository
}
path = "index.html"
} else {
@ -152,8 +169,13 @@ func (module GiteaPagesModule) ServeHTTP(writer http.ResponseWriter, request *ht
}
} else {
// (Try to) Use of the pages repository in the specified organization
// We use github.com conventions: <organization>.github.io
repository = organization + "." + module.PostfixPagesRepository
// Determine name of the default repository for organization based on settings
if module.PagesRepository != "" {
repository = module.PagesRepository
} else {
// We use github.com conventions: <organization>.github.io
repository = organization + "." + module.PostfixPagesRepository
}
path = strings.Join(parts[0:], "/")
}
}
@ -162,11 +184,20 @@ func (module GiteaPagesModule) ServeHTTP(writer http.ResponseWriter, request *ht
// Handle request
content, err := module.getFile(organization, repository, module.PagesBranch, path)
if err != nil {
return caddyhttp.Error(http.StatusNotFound, err)
module.Logger.Error("Unable to retrieve file: " + path + " - error: " + err.Error())
// append an index.html and retry
path = path + "/index.html"
content, err = module.getFile(organization, repository, module.PagesBranch, path)
if err != nil {
module.Logger.Error("Unable to retrieve file: " + path + " - error: " + err.Error())
return caddyhttp.Error(http.StatusNotFound, err)
}
// return caddyhttp.Error(http.StatusNotFound, err)
}
// Try to determine mime type based on extenstion of file
parts := strings.Split(request.URL.Path, ".")
parts := strings.Split(path, ".")
if len(parts) > 1 {
extension := parts[len(parts)-1] // get file extension
writer.Header().Add("Content-Type", mime.TypeByExtension("."+extension))
@ -194,21 +225,6 @@ func (module GiteaPagesModule) repoBranchExists(organization, repository, branch
return branchInfo.Name == branch
}
// Check if a repo has a specific topic assigned
func (module GiteaPagesModule) topicExists(organization, repository, topic string) bool {
topics, _, err := module.GiteaClient.ListRepoTopics(organization, repository, gitea.ListRepoTopicsOptions{})
if err != nil {
return false
}
for _, topicName := range topics {
if topicName == topic {
return true
}
}
return false
}
// Interface guards
var (
_ caddy.Provisioner = (*GiteaPagesModule)(nil)