mirror of https://github.com/portainer/portainer
feat(version): show git commit and env [EE-6021] (#10748)
parent
52db4cba0e
commit
4a10c2bb07
|
@ -110,6 +110,8 @@ jobs:
|
||||||
export YARN_VERSION=$(yarn --version)
|
export YARN_VERSION=$(yarn --version)
|
||||||
export WEBPACK_VERSION=$(yarn list webpack --depth=0 | grep webpack | awk -F@ '{print $2}')
|
export WEBPACK_VERSION=$(yarn list webpack --depth=0 | grep webpack | awk -F@ '{print $2}')
|
||||||
export BUILDNUMBER=${GITHUB_RUN_NUMBER}
|
export BUILDNUMBER=${GITHUB_RUN_NUMBER}
|
||||||
|
GIT_COMMIT_HASH_LONG=${{ github.sha }}
|
||||||
|
export GIT_COMMIT_HASH_SHORT={GIT_COMMIT_HASH_LONG:0:7}
|
||||||
make build-all PLATFORM=${{ matrix.config.platform }} ARCH=${{ matrix.config.arch }} ENV=${NODE_ENV}
|
make build-all PLATFORM=${{ matrix.config.platform }} ARCH=${{ matrix.config.arch }} ENV=${NODE_ENV}
|
||||||
env:
|
env:
|
||||||
CONTAINER_IMAGE_TAG: ${{ env.CONTAINER_IMAGE_TAG }}
|
CONTAINER_IMAGE_TAG: ${{ env.CONTAINER_IMAGE_TAG }}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package build
|
package build
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
// Variables to be set during the build time
|
// Variables to be set during the build time
|
||||||
var BuildNumber string
|
var BuildNumber string
|
||||||
var ImageTag string
|
var ImageTag string
|
||||||
var NodejsVersion string
|
var NodejsVersion string
|
||||||
var YarnVersion string
|
var YarnVersion string
|
||||||
var WebpackVersion string
|
var WebpackVersion string
|
||||||
var GoVersion string
|
var GoVersion string = runtime.Version()
|
||||||
|
var GitCommit string
|
||||||
|
|
|
@ -47,7 +47,7 @@ func NewHandler(bouncer security.BouncerService,
|
||||||
authenticatedRouter := router.PathPrefix("/").Subrouter()
|
authenticatedRouter := router.PathPrefix("/").Subrouter()
|
||||||
authenticatedRouter.Use(bouncer.AuthenticatedAccess)
|
authenticatedRouter.Use(bouncer.AuthenticatedAccess)
|
||||||
|
|
||||||
authenticatedRouter.Handle("/version", http.HandlerFunc(h.version)).Methods(http.MethodGet)
|
authenticatedRouter.Handle("/version", httperror.LoggerHandler(h.version)).Methods(http.MethodGet)
|
||||||
authenticatedRouter.Handle("/nodes", httperror.LoggerHandler(h.systemNodesCount)).Methods(http.MethodGet)
|
authenticatedRouter.Handle("/nodes", httperror.LoggerHandler(h.systemNodesCount)).Methods(http.MethodGet)
|
||||||
authenticatedRouter.Handle("/info", httperror.LoggerHandler(h.systemInfo)).Methods(http.MethodGet)
|
authenticatedRouter.Handle("/info", httperror.LoggerHandler(h.systemInfo)).Methods(http.MethodGet)
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,13 @@ package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
portainer "github.com/portainer/portainer/api"
|
portainer "github.com/portainer/portainer/api"
|
||||||
"github.com/portainer/portainer/api/build"
|
"github.com/portainer/portainer/api/build"
|
||||||
"github.com/portainer/portainer/api/http/client"
|
"github.com/portainer/portainer/api/http/client"
|
||||||
|
"github.com/portainer/portainer/api/http/security"
|
||||||
|
httperror "github.com/portainer/portainer/pkg/libhttp/error"
|
||||||
"github.com/portainer/portainer/pkg/libhttp/response"
|
"github.com/portainer/portainer/pkg/libhttp/response"
|
||||||
|
|
||||||
"github.com/coreos/go-semver/semver"
|
"github.com/coreos/go-semver/semver"
|
||||||
|
@ -32,6 +35,8 @@ type BuildInfo struct {
|
||||||
YarnVersion string
|
YarnVersion string
|
||||||
WebpackVersion string
|
WebpackVersion string
|
||||||
GoVersion string
|
GoVersion string
|
||||||
|
GitCommit string
|
||||||
|
Env []string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// @id systemVersion
|
// @id systemVersion
|
||||||
|
@ -44,7 +49,11 @@ type BuildInfo struct {
|
||||||
// @produce json
|
// @produce json
|
||||||
// @success 200 {object} versionResponse "Success"
|
// @success 200 {object} versionResponse "Success"
|
||||||
// @router /system/version [get]
|
// @router /system/version [get]
|
||||||
func (handler *Handler) version(w http.ResponseWriter, r *http.Request) {
|
func (handler *Handler) version(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||||
|
isAdmin, err := security.IsAdmin(r)
|
||||||
|
if err != nil {
|
||||||
|
return httperror.Forbidden("Permission denied to access Portainer", err)
|
||||||
|
}
|
||||||
|
|
||||||
result := &versionResponse{
|
result := &versionResponse{
|
||||||
ServerVersion: portainer.APIVersion,
|
ServerVersion: portainer.APIVersion,
|
||||||
|
@ -57,16 +66,21 @@ func (handler *Handler) version(w http.ResponseWriter, r *http.Request) {
|
||||||
YarnVersion: build.YarnVersion,
|
YarnVersion: build.YarnVersion,
|
||||||
WebpackVersion: build.WebpackVersion,
|
WebpackVersion: build.WebpackVersion,
|
||||||
GoVersion: build.GoVersion,
|
GoVersion: build.GoVersion,
|
||||||
|
GitCommit: build.GitCommit,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isAdmin {
|
||||||
|
result.Build.Env = os.Environ()
|
||||||
|
}
|
||||||
|
|
||||||
latestVersion := GetLatestVersion()
|
latestVersion := GetLatestVersion()
|
||||||
if HasNewerVersion(portainer.APIVersion, latestVersion) {
|
if HasNewerVersion(portainer.APIVersion, latestVersion) {
|
||||||
result.UpdateAvailable = true
|
result.UpdateAvailable = true
|
||||||
result.LatestVersion = latestVersion
|
result.LatestVersion = latestVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
response.JSON(w, &result)
|
return response.JSON(w, &result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLatestVersion() string {
|
func GetLatestVersion() string {
|
||||||
|
|
|
@ -21,6 +21,8 @@ export interface VersionResponse {
|
||||||
YarnVersion: string;
|
YarnVersion: string;
|
||||||
WebpackVersion: string;
|
WebpackVersion: string;
|
||||||
GoVersion: string;
|
GoVersion: string;
|
||||||
|
GitCommit: string;
|
||||||
|
Env?: string[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Database, Hash, Server, Tag, Wrench } from 'lucide-react';
|
import {
|
||||||
|
Database,
|
||||||
|
GitCommit,
|
||||||
|
Hash,
|
||||||
|
Server,
|
||||||
|
Tag,
|
||||||
|
Variable,
|
||||||
|
Wrench,
|
||||||
|
} from 'lucide-react';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { useSystemStatus } from '@/react/portainer/system/useSystemStatus';
|
import { useSystemStatus } from '@/react/portainer/system/useSystemStatus';
|
||||||
import { useSystemVersion } from '@/react/portainer/system/useSystemVersion';
|
import { useSystemVersion } from '@/react/portainer/system/useSystemVersion';
|
||||||
|
import { useCurrentUser } from '@/react/hooks/useUser';
|
||||||
|
|
||||||
import { Modal } from '@@/modals';
|
import { Modal } from '@@/modals';
|
||||||
import { Button } from '@@/buttons';
|
import { Button } from '@@/buttons';
|
||||||
|
@ -37,6 +47,7 @@ export function BuildInfoModalButton() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function BuildInfoModal({ closeModal }: { closeModal: () => void }) {
|
function BuildInfoModal({ closeModal }: { closeModal: () => void }) {
|
||||||
|
const { isAdmin } = useCurrentUser();
|
||||||
const versionQuery = useSystemVersion();
|
const versionQuery = useSystemVersion();
|
||||||
const statusQuery = useSystemStatus();
|
const statusQuery = useSystemStatus();
|
||||||
|
|
||||||
|
@ -82,6 +93,13 @@ function BuildInfoModal({ closeModal }: { closeModal: () => void }) {
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<GitCommit size="13" className="space-right" />
|
||||||
|
Git Commit: {Build.GitCommit}
|
||||||
|
</td>
|
||||||
|
<td />
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -102,6 +120,25 @@ function BuildInfoModal({ closeModal }: { closeModal: () => void }) {
|
||||||
<span className="text-muted small">Go v{Build.GoVersion}</span>
|
<span className="text-muted small">Go v{Build.GoVersion}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isAdmin && Build.Env && (
|
||||||
|
<div className={clsx(styles.toolsList, 'mt-3')}>
|
||||||
|
<span className="inline-flex items-center ">
|
||||||
|
<Variable size="13" className="space-right" />
|
||||||
|
Environment Variables
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={clsx(styles.tools, 'max-h-32 overflow-auto space-y-2')}
|
||||||
|
>
|
||||||
|
{Build.Env.map((envVar) => (
|
||||||
|
<div key={envVar}>
|
||||||
|
<code>{envVar}</code>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
<Modal.Footer>
|
<Modal.Footer>
|
||||||
<Button className="w-full" onClick={closeModal}>
|
<Button className="w-full" onClick={closeModal}>
|
||||||
|
|
|
@ -4,12 +4,14 @@ set -euo pipefail
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
|
|
||||||
# populate tool versions
|
# populate tool versions
|
||||||
|
|
||||||
BUILDNUMBER=${BUILDNUMBER:-"N/A"}
|
BUILDNUMBER=${BUILDNUMBER:-"N/A"}
|
||||||
CONTAINER_IMAGE_TAG=${CONTAINER_IMAGE_TAG:-"N/A"}
|
CONTAINER_IMAGE_TAG=${CONTAINER_IMAGE_TAG:-"N/A"}
|
||||||
NODE_VERSION=${NODE_VERSION:-"N/A"}
|
NODE_VERSION=${NODE_VERSION:-$(node -v)}
|
||||||
YARN_VERSION=${YARN_VERSION:-"N/A"}
|
YARN_VERSION=${YARN_VERSION:-$(yarn --version))}
|
||||||
WEBPACK_VERSION=${WEBPACK_VERSION:-"N/A"}
|
WEBPACK_VERSION=${WEBPACK_VERSION:-$(yarn list webpack --depth=0 | grep webpack | awk -F@ '{print $2}')}
|
||||||
GO_VERSION=${GO_VERSION:-"N/A"}
|
GO_VERSION=${GO_VERSION:-$(go version | awk '{print $3}')}
|
||||||
|
GIT_COMMIT_HASH=${GIT_COMMIT_HASH:-$(git rev-parse --short HEAD)}
|
||||||
|
|
||||||
# copy templates
|
# copy templates
|
||||||
cp -r "./mustache-templates" "./dist"
|
cp -r "./mustache-templates" "./dist"
|
||||||
|
@ -26,6 +28,7 @@ ldflags="-s -X 'github.com/portainer/liblicense.LicenseServerBaseURL=https://api
|
||||||
-X 'github.com/portainer/portainer/api/build.NodejsVersion=${NODE_VERSION}' \
|
-X 'github.com/portainer/portainer/api/build.NodejsVersion=${NODE_VERSION}' \
|
||||||
-X 'github.com/portainer/portainer/api/build.YarnVersion=${YARN_VERSION}' \
|
-X 'github.com/portainer/portainer/api/build.YarnVersion=${YARN_VERSION}' \
|
||||||
-X 'github.com/portainer/portainer/api/build.WebpackVersion=${WEBPACK_VERSION}' \
|
-X 'github.com/portainer/portainer/api/build.WebpackVersion=${WEBPACK_VERSION}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.GitCommit=${GIT_COMMIT_HASH}' \
|
||||||
-X 'github.com/portainer/portainer/api/build.GoVersion=${GO_VERSION}'"
|
-X 'github.com/portainer/portainer/api/build.GoVersion=${GO_VERSION}'"
|
||||||
|
|
||||||
BINARY_VERSION_FILE="../binary-version.json"
|
BINARY_VERSION_FILE="../binary-version.json"
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
"js-yaml": "^3.14.0",
|
"js-yaml": "^3.14.0",
|
||||||
"jsdom": "^24.0.0",
|
"jsdom": "^24.0.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"lucide-react": "^0.101.0",
|
"lucide-react": "^0.258.0",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"moment-timezone": "^0.5.40",
|
"moment-timezone": "^0.5.40",
|
||||||
"mustache": "^4.2.0",
|
"mustache": "^4.2.0",
|
||||||
|
|
|
@ -12478,10 +12478,10 @@ lru-cache@^6.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484"
|
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484"
|
||||||
integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==
|
integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==
|
||||||
|
|
||||||
lucide-react@^0.101.0:
|
lucide-react@^0.258.0:
|
||||||
version "0.101.0"
|
version "0.258.0"
|
||||||
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.101.0.tgz#0d5c00748c9c7f2a0e7e8b85acff9e5492c8fdcb"
|
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.258.0.tgz#dbdabafad2835a0a452e8f677531a877cdd93ae8"
|
||||||
integrity sha512-jziosG8Cvqk19et2srzNidxvewTsPiNM8fWc5WSzdeZX1GC8w9PZWG+oXwVU5yy/LWMBCjgVicrmtmp6wWxCDw==
|
integrity sha512-3evnpKadBrjLr2HHJ66eDZ1y0vPS6pm8NiNDaLqhddUUyJGnA+lfDPZfbVkuAFq7Xaa1TEy7Sg17sM7mHpMKrA==
|
||||||
|
|
||||||
lz-string@^1.4.4:
|
lz-string@^1.4.4:
|
||||||
version "1.4.4"
|
version "1.4.4"
|
||||||
|
|
Loading…
Reference in New Issue