mirror of
https://codeberg.org/git-pages/git-pages.git
synced 2026-05-14 11:11:35 +00:00
Unpublish site when pushing an empty repository.
This commit is contained in:
@@ -42,6 +42,7 @@ Features
|
||||
* In response to a `PUT` or `POST` request, the server performs a shallow clone of the indicated git repository into a temporary location, checks out the `HEAD` commit, and atomically updates a site. The URL of the request must be the root URL of the site that is being published.
|
||||
- The `PUT` method requires an `application/x-www-form-urlencoded` body. The body contains the repository URL to be cloned.
|
||||
- The `POST` method requires an `application/json` body containing a Forgejo/Gitea/Gogs/GitHub webhook event payload. Requests where the `ref` key contains anything other than `refs/heads/pages` are ignored. The `repository.clone_url` key contains the repository URL to be cloned.
|
||||
- If the `HEAD` commit is empty, performs the same action as `DELETE`.
|
||||
* In response to a `DELETE` request, the server unpublishes a site. The URL of the request must be the root URL of the site that is being unpublished. Site data remains stored for an indeterminate period of time, but becomes completely inaccessible.
|
||||
* All updates to site content are atomic (subject to consistency guarantees of the storage backend). That is, there is an instantaneous moment during an update before which the server will return the old content and after which it will return the new content.
|
||||
|
||||
|
||||
@@ -12,6 +12,18 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func IsManifestEmpty(manifest *Manifest) bool {
|
||||
if len(manifest.Tree) > 1 {
|
||||
return false
|
||||
}
|
||||
for name, entry := range manifest.Tree {
|
||||
if name == "" && entry.Type == Type_Directory {
|
||||
return true
|
||||
}
|
||||
}
|
||||
panic(fmt.Errorf("malformed manifest %v", manifest))
|
||||
}
|
||||
|
||||
// Returns `true` if `left` and `right` contain the same files with the same types and data.
|
||||
func CompareManifest(left *Manifest, right *Manifest) bool {
|
||||
if len(left.Tree) != len(right.Tree) {
|
||||
|
||||
15
src/pages.go
15
src/pages.go
@@ -192,21 +192,19 @@ func putPage(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), updateTimeout)
|
||||
defer cancel()
|
||||
result := Update(ctx, webRoot, repoURL, branch)
|
||||
if result.manifest != nil {
|
||||
w.Header().Add("Content-Location", r.URL.String())
|
||||
}
|
||||
switch result.outcome {
|
||||
case UpdateError:
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
case UpdateTimeout:
|
||||
w.WriteHeader(http.StatusGatewayTimeout)
|
||||
// HTTP prescribes these response codes to be used
|
||||
case UpdateNoChange:
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
w.Header().Add("X-Pages-Outcome", "no-change")
|
||||
case UpdateCreated:
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Header().Add("X-Pages-Outcome", "created")
|
||||
case UpdateReplaced:
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Header().Add("X-Pages-Outcome", "replaced")
|
||||
case UpdateDeleted:
|
||||
w.Header().Add("X-Pages-Outcome", "deleted")
|
||||
}
|
||||
if result.manifest != nil {
|
||||
fmt.Fprintln(w, result.manifest.Commit)
|
||||
@@ -331,6 +329,9 @@ func postPage(w http.ResponseWriter, r *http.Request) error {
|
||||
case UpdateReplaced:
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintln(w, "replaced")
|
||||
case UpdateDeleted:
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintln(w, "deleted")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ const (
|
||||
UpdateTimeout
|
||||
UpdateCreated
|
||||
UpdateReplaced
|
||||
UpdateDeleted
|
||||
UpdateNoChange
|
||||
)
|
||||
|
||||
@@ -41,14 +42,25 @@ func Update(
|
||||
err = fmt.Errorf("update timeout")
|
||||
} else if err == nil {
|
||||
oldManifest, _ = backend.GetManifest(webRoot)
|
||||
newManifest, err = StoreManifest(webRoot, fetchManifest)
|
||||
if err == nil {
|
||||
if oldManifest == nil {
|
||||
outcome = UpdateCreated
|
||||
} else if CompareManifest(oldManifest, newManifest) {
|
||||
outcome = UpdateNoChange
|
||||
} else {
|
||||
outcome = UpdateReplaced
|
||||
if IsManifestEmpty(fetchManifest) {
|
||||
newManifest, err = fetchManifest, backend.DeleteManifest(webRoot)
|
||||
if err == nil {
|
||||
if oldManifest == nil {
|
||||
outcome = UpdateNoChange
|
||||
} else {
|
||||
outcome = UpdateDeleted
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newManifest, err = StoreManifest(webRoot, fetchManifest)
|
||||
if err == nil {
|
||||
if oldManifest == nil {
|
||||
outcome = UpdateCreated
|
||||
} else if CompareManifest(oldManifest, newManifest) {
|
||||
outcome = UpdateNoChange
|
||||
} else {
|
||||
outcome = UpdateReplaced
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,6 +72,8 @@ func Update(
|
||||
status = "created"
|
||||
case UpdateReplaced:
|
||||
status = "replaced"
|
||||
case UpdateDeleted:
|
||||
status = "deleted"
|
||||
case UpdateNoChange:
|
||||
status = "unchanged"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user