Commit 94ce1e53 authored by boojack's avatar boojack

chore(settings): show build commit in version info

parent e2c60845
......@@ -37,6 +37,7 @@ var (
InstanceURL: viper.GetString("instance-url"),
}
instanceProfile.Version = version.GetCurrentVersion()
instanceProfile.Commit = version.Commit
webhook.AllowPrivateIPs = viper.GetBool("allow-private-webhooks")
if err := instanceProfile.Validate(); err != nil {
......
......@@ -30,6 +30,8 @@ type Profile struct {
Driver string
// Version is the current version of server
Version string
// Commit is the current build commit of server
Commit string
// InstanceURL is the url of your memos instance.
InstanceURL string
}
......
......@@ -48,6 +48,9 @@ message InstanceProfile {
// The first administrator who set up this instance.
// When null, instance requires initial setup (creating the first admin account).
User admin = 7;
// Commit is the current build commit of instance.
string commit = 8;
}
// Request for instance profile.
......
......@@ -210,6 +210,8 @@ type InstanceProfile struct {
// The first administrator who set up this instance.
// When null, instance requires initial setup (creating the first admin account).
Admin *User `protobuf:"bytes,7,opt,name=admin,proto3" json:"admin,omitempty"`
// Commit is the current build commit of instance.
Commit string `protobuf:"bytes,8,opt,name=commit,proto3" json:"commit,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
......@@ -272,6 +274,13 @@ func (x *InstanceProfile) GetAdmin() *User {
return nil
}
func (x *InstanceProfile) GetCommit() string {
if x != nil {
return x.Commit
}
return ""
}
// Request for instance profile.
type GetInstanceProfileRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
......@@ -1377,12 +1386,13 @@ var File_api_v1_instance_service_proto protoreflect.FileDescriptor
const file_api_v1_instance_service_proto_rawDesc = "" +
"\n" +
"\x1dapi/v1/instance_service.proto\x12\fmemos.api.v1\x1a\x19api/v1/user_service.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a google/protobuf/field_mask.proto\x1a\x17google/type/color.proto\"\x8c\x01\n" +
"\x1dapi/v1/instance_service.proto\x12\fmemos.api.v1\x1a\x19api/v1/user_service.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a google/protobuf/field_mask.proto\x1a\x17google/type/color.proto\"\xa4\x01\n" +
"\x0fInstanceProfile\x12\x18\n" +
"\aversion\x18\x02 \x01(\tR\aversion\x12\x12\n" +
"\x04demo\x18\x03 \x01(\bR\x04demo\x12!\n" +
"\finstance_url\x18\x06 \x01(\tR\vinstanceUrl\x12(\n" +
"\x05admin\x18\a \x01(\v2\x12.memos.api.v1.UserR\x05admin\"\x1b\n" +
"\x05admin\x18\a \x01(\v2\x12.memos.api.v1.UserR\x05admin\x12\x16\n" +
"\x06commit\x18\b \x01(\tR\x06commit\"\x1b\n" +
"\x19GetInstanceProfileRequest\"\xe6\x19\n" +
"\x0fInstanceSetting\x12\x17\n" +
"\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12W\n" +
......
......@@ -2530,6 +2530,9 @@ components:
description: |-
The first administrator who set up this instance.
When null, instance requires initial setup (creating the first admin account).
commit:
type: string
description: Commit is the current build commit of instance.
description: Instance profile message containing basic instance information.
InstanceSetting:
type: object
......
......@@ -30,6 +30,7 @@ func (s *APIV1Service) GetInstanceProfile(ctx context.Context, _ *v1pb.GetInstan
Demo: s.Profile.Demo,
InstanceUrl: s.Profile.InstanceURL,
Admin: admin, // nil when not initialized
Commit: s.Profile.Commit,
}
return instanceProfile, nil
}
......
......@@ -29,6 +29,7 @@ func TestGetInstanceProfile(t *testing.T) {
// Verify the response contains expected data
require.Equal(t, "test-1.0.0", resp.Version)
require.Equal(t, "test-commit", resp.Commit)
require.True(t, resp.Demo)
require.Equal(t, "http://localhost:8080", resp.InstanceUrl)
......@@ -56,6 +57,7 @@ func TestGetInstanceProfile(t *testing.T) {
// Verify the response contains expected data with initialized flag
require.Equal(t, "test-1.0.0", resp.Version)
require.Equal(t, "test-commit", resp.Commit)
require.True(t, resp.Demo)
require.Equal(t, "http://localhost:8080", resp.InstanceUrl)
......@@ -102,6 +104,7 @@ func TestGetInstanceProfile_Concurrency(t *testing.T) {
case resp := <-results:
require.NotNil(t, resp)
require.Equal(t, "test-1.0.0", resp.Version)
require.Equal(t, "test-commit", resp.Commit)
require.True(t, resp.Demo)
require.Equal(t, "http://localhost:8080", resp.InstanceUrl)
require.NotNil(t, resp.Admin)
......
......@@ -32,6 +32,7 @@ func NewTestService(t *testing.T) *TestService {
testProfile := &profile.Profile{
Demo: true,
Version: "test-1.0.0",
Commit: "test-commit",
InstanceURL: "http://localhost:8080",
Driver: "sqlite",
DSN: ":memory:",
......
......@@ -37,6 +37,9 @@ type SettingSection = "my-account" | "preference" | "webhook" | "member" | "syst
const BASIC_SECTIONS: SettingSection[] = ["my-account", "preference", "webhook"];
const ADMIN_SECTIONS: SettingSection[] = ["member", "system", "memo", "tags", "storage", "sso", "ai"];
const GITHUB_COMMIT_URL_PREFIX = "https://github.com/usememos/memos/commit/";
const isCommitSha = (commit: string) => /^[0-9a-f]{7,40}$/i.test(commit);
const SECTION_ICON_MAP: Record<SettingSection, LucideIcon> = {
"my-account": UserIcon,
......@@ -72,6 +75,7 @@ const Setting = () => {
const { profile, fetchSetting } = useInstance();
const [selectedSection, setSelectedSection] = useState<SettingSection>("my-account");
const isHost = user?.role === User_Role.ADMIN;
const commitUrl = isCommitSha(profile.commit) ? `${GITHUB_COMMIT_URL_PREFIX}${profile.commit}` : "";
const settingsSectionList = useMemo(() => {
return isHost ? [...BASIC_SECTIONS, ...ADMIN_SECTIONS] : [...BASIC_SECTIONS];
......@@ -131,9 +135,21 @@ const Setting = () => {
onClick={() => handleSectionSelectorItemClick(item)}
/>
))}
<span className="px-3 mt-2 opacity-70 text-sm">
{t("setting.version")}: v{profile.version}
<div className="px-3 mt-2 opacity-70 text-sm leading-5">
{t("setting.version")}: {profile.version}
{profile.commit && (
<span className="block font-mono break-all">
Commit:{" "}
{commitUrl ? (
<a className="underline hover:text-foreground" href={commitUrl} target="_blank" rel="noreferrer">
{profile.commit}
</a>
) : (
profile.commit
)}
</span>
)}
</div>
</div>
</>
)}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment