mirror of
https://github.com/simongregorebner/gitea-pages.git
synced 2025-06-07 22:10:41 +02:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
711845d6be | ||
![]() |
d4e3b4bd88 | ||
4267eb2661 | |||
02abc7bcde | |||
ec8227b98d | |||
02fae34477 | |||
7f2f378741 | |||
0842be001b | |||
28b9ac94f5 | |||
94dd5396ad | |||
f8b70e8cb9 | |||
f88e09b481 | |||
411bc54f6b |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
caddy
|
caddy
|
||||||
Caddyfile
|
Caddyfile
|
||||||
|
Caddyfile_gitea-test.psi.ch
|
@ -1,6 +1,6 @@
|
|||||||
FROM caddy:builder-alpine AS builder
|
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
|
FROM alpine
|
||||||
|
28
Readme.md
28
Readme.md
@ -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>__
|
__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
|
## Classic Mode
|
||||||
|
|
||||||
In __classic__ mode the access to the pages goes according to these two patterns:
|
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>__
|
__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.
|
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
|
# 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_):
|
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. |
|
| 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.|
|
| 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" |
|
| 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 |
|
| 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
|
# example build image for this github user
|
||||||
docker build --platform=linux/amd64 -t ghcr.io/simongregorebner/gitea-pages:0.0.1 .
|
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
|
## Testing
|
||||||
|
12
docker-compose.yml
Normal file
12
docker-compose.yml
Normal 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"
|
@ -6,6 +6,7 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
@ -34,6 +35,7 @@ type GiteaPagesModule struct {
|
|||||||
Server string `json:"server,omitempty"`
|
Server string `json:"server,omitempty"`
|
||||||
Token string `json:"token,omitempty"`
|
Token string `json:"token,omitempty"`
|
||||||
PagesBranch string `json:"pages_branch,omitempty"`
|
PagesBranch string `json:"pages_branch,omitempty"`
|
||||||
|
PagesRepository string `json:"pages_repository,omitempty"`
|
||||||
PostfixPagesRepository string `json:"postfix_pages_repository,omitempty"`
|
PostfixPagesRepository string `json:"postfix_pages_repository,omitempty"`
|
||||||
URLScheme string `json:"url_scheme,omitempty"`
|
URLScheme string `json:"url_scheme,omitempty"`
|
||||||
}
|
}
|
||||||
@ -65,6 +67,8 @@ func (module *GiteaPagesModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error
|
|||||||
d.Args(&module.Token)
|
d.Args(&module.Token)
|
||||||
case "pages_branch":
|
case "pages_branch":
|
||||||
d.Args(&module.PagesBranch)
|
d.Args(&module.PagesBranch)
|
||||||
|
case "pages_repository":
|
||||||
|
d.Args(&module.PagesRepository)
|
||||||
case "postfix_pages_repository":
|
case "postfix_pages_repository":
|
||||||
d.Args(&module.PostfixPagesRepository)
|
d.Args(&module.PostfixPagesRepository)
|
||||||
case "url_scheme":
|
case "url_scheme":
|
||||||
@ -76,8 +80,10 @@ func (module *GiteaPagesModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error
|
|||||||
if module.PagesBranch == "" {
|
if module.PagesBranch == "" {
|
||||||
module.PagesBranch = "gitea-pages"
|
module.PagesBranch = "gitea-pages"
|
||||||
}
|
}
|
||||||
if module.PostfixPagesRepository == "" {
|
if module.PagesRepository == "" {
|
||||||
module.PostfixPagesRepository = "gitea-pages"
|
if module.PostfixPagesRepository == "" {
|
||||||
|
module.PostfixPagesRepository = "gitea-pages"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if module.URLScheme == "" {
|
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 {
|
func (module GiteaPagesModule) ServeHTTP(writer http.ResponseWriter, request *http.Request, _ caddyhttp.Handler) error {
|
||||||
|
|
||||||
var organization, repository, path string
|
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" {
|
if module.URLScheme == "simple" {
|
||||||
// "Simple" URL case - we expect the organization and repository in the URL
|
// "Simple" URL case - we expect the organization and repository in the URL
|
||||||
// The URL/path looks like http(s)://<giteaserver>[:<port>]/<organization>/<repository>[/<filepath>]
|
// The URL/path looks like http(s)://<giteaserver>[:<port>]/<organization>/<repository>[/<filepath>]
|
||||||
|
|
||||||
// Remove a potential "/" prefix and trailing "/" - then split up the path
|
// 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)
|
length := len(parts)
|
||||||
if length <= 1 {
|
if length <= 1 {
|
||||||
@ -125,14 +137,19 @@ func (module GiteaPagesModule) ServeHTTP(writer http.ResponseWriter, request *ht
|
|||||||
organization = strings.Split(request.Host, ".")[0]
|
organization = strings.Split(request.Host, ".")[0]
|
||||||
|
|
||||||
// Remove a potential "/" prefix and trailing "/" - then split up the path
|
// 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 == "" {
|
if path == "" {
|
||||||
// Case http(s)://<organization>.<giteaserver>[:<port>]
|
// Case http(s)://<organization>.<giteaserver>[:<port>]
|
||||||
// (Try to) Use of the pages repository in the specified organization
|
// (Try to) Use of the pages repository in the specified organization
|
||||||
|
|
||||||
// We use github.com conventions: <organization>.github.io
|
// Determine name of the default repository for organization based on settings
|
||||||
repository = organization + "." + module.PostfixPagesRepository
|
if module.PagesRepository != "" {
|
||||||
|
repository = module.PagesRepository
|
||||||
|
} else {
|
||||||
|
// We use github.com conventions: <organization>.github.io
|
||||||
|
repository = organization + "." + module.PostfixPagesRepository
|
||||||
|
}
|
||||||
path = "index.html"
|
path = "index.html"
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -152,8 +169,13 @@ func (module GiteaPagesModule) ServeHTTP(writer http.ResponseWriter, request *ht
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// (Try to) Use of the pages repository in the specified organization
|
// (Try to) Use of the pages repository in the specified organization
|
||||||
// We use github.com conventions: <organization>.github.io
|
// Determine name of the default repository for organization based on settings
|
||||||
repository = organization + "." + module.PostfixPagesRepository
|
if module.PagesRepository != "" {
|
||||||
|
repository = module.PagesRepository
|
||||||
|
} else {
|
||||||
|
// We use github.com conventions: <organization>.github.io
|
||||||
|
repository = organization + "." + module.PostfixPagesRepository
|
||||||
|
}
|
||||||
path = strings.Join(parts[0:], "/")
|
path = strings.Join(parts[0:], "/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,11 +184,20 @@ func (module GiteaPagesModule) ServeHTTP(writer http.ResponseWriter, request *ht
|
|||||||
// Handle request
|
// Handle request
|
||||||
content, err := module.getFile(organization, repository, module.PagesBranch, path)
|
content, err := module.getFile(organization, repository, module.PagesBranch, path)
|
||||||
if err != nil {
|
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
|
// Try to determine mime type based on extenstion of file
|
||||||
parts := strings.Split(request.URL.Path, ".")
|
parts := strings.Split(path, ".")
|
||||||
if len(parts) > 1 {
|
if len(parts) > 1 {
|
||||||
extension := parts[len(parts)-1] // get file extension
|
extension := parts[len(parts)-1] // get file extension
|
||||||
writer.Header().Add("Content-Type", mime.TypeByExtension("."+extension))
|
writer.Header().Add("Content-Type", mime.TypeByExtension("."+extension))
|
||||||
@ -194,21 +225,6 @@ func (module GiteaPagesModule) repoBranchExists(organization, repository, branch
|
|||||||
return branchInfo.Name == 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
|
// Interface guards
|
||||||
var (
|
var (
|
||||||
_ caddy.Provisioner = (*GiteaPagesModule)(nil)
|
_ caddy.Provisioner = (*GiteaPagesModule)(nil)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user