diff --git a/client/client.go b/client/client.go index 3464e293..23ff3d07 100644 --- a/client/client.go +++ b/client/client.go @@ -30,6 +30,22 @@ func New(endpoint string, credentials ...string) *Client { return &Client{request: &request{endpoint: endpoint, apiKey: credentials[0]}} } +// Version returns the version of the Miniflux instance. +func (c *Client) Version() (*VersionResponse, error) { + body, err := c.request.Get("/v1/version") + if err != nil { + return nil, err + } + defer body.Close() + + var versionResponse *VersionResponse + if err := json.NewDecoder(body).Decode(&versionResponse); err != nil { + return nil, fmt.Errorf("miniflux: json error (%v)", err) + } + + return versionResponse, nil +} + // Me returns the logged user information. func (c *Client) Me() (*User, error) { body, err := c.request.Get("/v1/me") diff --git a/client/model.go b/client/model.go index a193d92c..4808b31d 100644 --- a/client/model.go +++ b/client/model.go @@ -276,3 +276,14 @@ type EntryResultSet struct { Total int `json:"total"` Entries Entries `json:"entries"` } + +// VersionResponse represents the version and the build information of the Miniflux instance. +type VersionResponse struct { + Version string `json:"version"` + Commit string `json:"commit"` + BuildDate string `json:"build_date"` + GoVersion string `json:"go_version"` + Compiler string `json:"compiler"` + Arch string `json:"arch"` + OS string `json:"os"` +} diff --git a/contrib/bruno/miniflux/Get version and build information.bru b/contrib/bruno/miniflux/Get version and build information.bru new file mode 100644 index 00000000..0b401364 --- /dev/null +++ b/contrib/bruno/miniflux/Get version and build information.bru @@ -0,0 +1,16 @@ +meta { + name: Get version and build information + type: http + seq: 42 +} + +get { + url: {{minifluxBaseURL}}/v1/version + body: none + auth: basic +} + +auth:basic { + username: {{minifluxUsername}} + password: {{minifluxPassword}} +} diff --git a/internal/api/api.go b/internal/api/api.go index d6a36376..2963a990 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -5,8 +5,11 @@ package api // import "miniflux.app/v2/internal/api" import ( "net/http" + "runtime" + "miniflux.app/v2/internal/http/response/json" "miniflux.app/v2/internal/storage" + "miniflux.app/v2/internal/version" "miniflux.app/v2/internal/worker" "github.com/gorilla/mux" @@ -69,4 +72,17 @@ func Serve(router *mux.Router, store *storage.Storage, pool *worker.Pool) { sr.HandleFunc("/entries/{entryID}/fetch-content", handler.fetchContent).Methods(http.MethodGet) sr.HandleFunc("/flush-history", handler.flushHistory).Methods(http.MethodPut, http.MethodDelete) sr.HandleFunc("/icons/{iconID}", handler.getIconByIconID).Methods(http.MethodGet) + sr.HandleFunc("/version", handler.versionHandler).Methods(http.MethodGet) +} + +func (h *handler) versionHandler(w http.ResponseWriter, r *http.Request) { + json.OK(w, r, &versionResponse{ + Version: version.Version, + Commit: version.Commit, + BuildDate: version.BuildDate, + GoVersion: runtime.Version(), + Compiler: runtime.Compiler, + Arch: runtime.GOARCH, + OS: runtime.GOOS, + }) } diff --git a/internal/api/payload.go b/internal/api/payload.go index 499d6a9e..cb0ce314 100644 --- a/internal/api/payload.go +++ b/internal/api/payload.go @@ -21,3 +21,13 @@ type entriesResponse struct { type feedCreationResponse struct { FeedID int64 `json:"feed_id"` } + +type versionResponse struct { + Version string `json:"version"` + Commit string `json:"commit"` + BuildDate string `json:"build_date"` + GoVersion string `json:"go_version"` + Compiler string `json:"compiler"` + Arch string `json:"arch"` + OS string `json:"os"` +} diff --git a/internal/tests/version_test.go b/internal/tests/version_test.go new file mode 100644 index 00000000..ebb11aa1 --- /dev/null +++ b/internal/tests/version_test.go @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//go:build integration +// +build integration + +package tests + +import ( + "testing" + + miniflux "miniflux.app/v2/client" +) + +func TestVersionEndpoint(t *testing.T) { + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + version, err := client.Version() + if err != nil { + t.Fatal(err) + } + + if version.Version == "" { + t.Fatal(`Version should not be empty`) + } + + if version.Commit == "" { + t.Fatal(`Commit should not be empty`) + } + + if version.BuildDate == "" { + t.Fatal(`Build date should not be empty`) + } + + if version.GoVersion == "" { + t.Fatal(`Go version should not be empty`) + } + + if version.Compiler == "" { + t.Fatal(`Compiler should not be empty`) + } + + if version.Arch == "" { + t.Fatal(`Arch should not be empty`) + } + + if version.OS == "" { + t.Fatal(`OS should not be empty`) + } +}