diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 434987e..a01afea 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -8,16 +8,14 @@ jobs: steps: - name: 输出当前目录环境 run: pwd && ls -ahl - - name: 输出github环境变量 - run: echo 'github相关 ${{ toJSON(github) }}' - - name: 拷贝文件 - run: cd ../ && cp -r . /root/runner/ - name: 发送通知 id: use-go-action uses: https://git.aweoo.com/action/gotify@latest with: - username: foo - - name: Print Output + url: https://gotify.aweoo.com + token: test_token + title: GotifyAction版本更新 + - name: 打印上一步的输出 run: echo 'output time is ${{ steps.use-go-action.outputs.time }}' - name: 错误处理 if: ${{ failure() }} diff --git a/Taskfile.yml b/Taskfile.yml index 7074af6..2fdd4db 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -10,7 +10,4 @@ tasks: - git push origin --tags - git push - cp: - cmds: - - cp -r ${GITHUB_WORKSPACE}../ /root/runner/ diff --git a/action.yaml b/action.yaml index b54023e..7c2fd8a 100644 --- a/action.yaml +++ b/action.yaml @@ -1,12 +1,29 @@ name: 'Gotify通知' description: '发送Gotify通知' inputs: - username: - description: 'The username to print' + url: + description: '地址 不需要/message' required: true + token: + description: "token" + required: true + title: + description: "标题" + required: true + msgText: + description: "消息内容" + contentType: + description: "消息格式" + default: "text/markdown" + priority: + description: "优先级" + clickUrl: + description: "点击跳转地址" + bigImageUrl: + description: "大图地址" outputs: time: - description: 'The time when the action was called' + description: '结束时间(无用)' runs: using: 'go' main: 'main.go' diff --git a/go.mod b/go.mod index 4d1b66f..f377c62 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/go-openapi/strfmt v0.17.0 // indirect github.com/go-openapi/swag v0.17.0 // indirect github.com/go-openapi/validate v0.17.0 // indirect + github.com/golang-cz/devslog v0.0.11 // indirect github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect github.com/mitchellh/mapstructure v1.1.2 // indirect github.com/spf13/cast v1.7.0 // indirect diff --git a/go.sum b/go.sum index 48dfc29..64f6a97 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,8 @@ github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi88 github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/validate v0.17.0 h1:pqoViQz3YLOGIhAmD0N4Lt6pa/3Gnj3ymKqQwq8iS6U= github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/golang-cz/devslog v0.0.11 h1:v4Yb9o0ZpuZ/D8ZrtVw1f9q5XrjnkxwHF1XmWwO8IHg= +github.com/golang-cz/devslog v0.0.11/go.mod h1:bSe5bm0A7Nyfqtijf1OMNgVJHlWEuVSXnkuASiE1vV8= github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gotify/go-api-client/v2 v2.0.4 h1:0w8skCr8aLBDKaQDg31LKKHUGF7rt7zdRpR+6cqIAlE= diff --git a/main.go b/main.go index 40216fc..a9c8ef9 100644 --- a/main.go +++ b/main.go @@ -3,57 +3,57 @@ package main import ( "encoding/json" "fmt" + "github.com/golang-cz/devslog" "github.com/gotify/go-api-client/v2/auth" "github.com/gotify/go-api-client/v2/client/message" "github.com/gotify/go-api-client/v2/gotify" "github.com/gotify/go-api-client/v2/models" "github.com/sethvargo/go-githubactions" "github.com/spf13/cast" - "io/fs" + "log" + "log/slog" "net/http" "net/url" "os" - "path/filepath" + "strings" "time" ) +func init() { + slogOpts := &slog.HandlerOptions{ + AddSource: false, + Level: slog.LevelDebug, + } + + opts := &devslog.Options{ + HandlerOptions: slogOpts, + MaxSlicePrintSize: 5, + SortKeys: true, + TimeFormat: "[15:04:05]", + StringerFormatter: true, + } + logger := slog.New(devslog.NewHandler(os.Stdout, opts)) + + slog.SetDefault(logger) +} + func main() { - //doPush() - //return - - ctx, err := githubactions.Context() - if err != nil { - panic(err) + if err := doPush(); err != nil { + slog.Error("推送失败", slog.Any("err", err)) + log.Fatalln(err) } - - body, err := json.Marshal(ctx) - if err != nil { - panic(err) - } - fmt.Printf("context: %s\n", string(body)) - - username := githubactions.GetInput("username") - fmt.Printf("username is %s\n", username) - - dir, _ := os.Getwd() - root := filepath.Join(dir, "../") - filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { - if d.IsDir() { - if d.Name() == ".git" { - return filepath.SkipDir - } - return nil - } - //body, _ = os.ReadFile(path) - fmt.Printf("path: %s\n", path) - //fmt.Printf("path: %s\n%s\n\n", path, string(body)) - return nil - }) + slog.Info("推送成功") githubactions.SetOutput("time", time.Now().Format("2006-01-02 15:04:05")) } -func doPush() { +func doPush() error { + + ctx, err := githubactions.Context() + if err != nil { + slog.Error("获取上下文失败", slog.Any("err", err)) + return err + } priority := githubactions.GetInput("priority") title := githubactions.GetInput("title") @@ -64,6 +64,8 @@ func doPush() { msgText := githubactions.GetInput("msgText") stringURL := githubactions.GetInput("url") + msgText += "\n\n" + getExtraMsg(ctx) + msg := &models.MessageExternal{ Message: msgText, Title: title, @@ -91,13 +93,13 @@ func doPush() { parsedURL, err := url.Parse(stringURL) if err != nil { - panic(err) + return err } - pushMessage(parsedURL, token, msg) + return pushMessage(parsedURL, token, msg) } -func pushMessage(parsedURL *url.URL, token string, msg *models.MessageExternal) { +func pushMessage(parsedURL *url.URL, token string, msg *models.MessageExternal) error { client := gotify.NewClient(parsedURL, &http.Client{}) @@ -105,231 +107,223 @@ func pushMessage(parsedURL *url.URL, token string, msg *models.MessageExternal) params.SetBody(msg) res, err := client.Message.CreateMessage(params, auth.TokenAuth(token)) if err == nil { - // todo成功 - response, _ := json.Marshal(res) - fmt.Println(string(response)) + slog.Info("推送结果", slog.Any("result", res)) + return nil } else { - panic(err) - // todo 错误处理 + return err } } -type GithubEnv struct { - Event struct { - After string `json:"after"` - Before string `json:"before"` - Commits []struct { - Added []interface{} `json:"added"` - Author struct { - Email string `json:"email"` - Name string `json:"name"` - Username string `json:"username"` - } `json:"author"` - Committer struct { - Email string `json:"email"` - Name string `json:"name"` - Username string `json:"username"` - } `json:"committer"` - Id string `json:"id"` - Message string `json:"message"` - Modified []string `json:"modified"` - Removed []interface{} `json:"removed"` - Timestamp time.Time `json:"timestamp"` - Url string `json:"url"` - Verification interface{} `json:"verification"` - } `json:"commits"` - CompareUrl string `json:"compare_url"` - HeadCommit struct { - Added []interface{} `json:"added"` - Author struct { - Email string `json:"email"` - Name string `json:"name"` - Username string `json:"username"` - } `json:"author"` - Committer struct { - Email string `json:"email"` - Name string `json:"name"` - Username string `json:"username"` - } `json:"committer"` - Id string `json:"id"` - Message string `json:"message"` - Modified []string `json:"modified"` - Removed []interface{} `json:"removed"` - Timestamp time.Time `json:"timestamp"` - Url string `json:"url"` - Verification interface{} `json:"verification"` - } `json:"head_commit"` - Pusher struct { - Active bool `json:"active"` - AvatarUrl string `json:"avatar_url"` - Created time.Time `json:"created"` - Description string `json:"description"` - Email string `json:"email"` - FollowersCount int `json:"followers_count"` - FollowingCount int `json:"following_count"` - FullName string `json:"full_name"` - HtmlUrl string `json:"html_url"` - Id int `json:"id"` - IsAdmin bool `json:"is_admin"` - Language string `json:"language"` - LastLogin time.Time `json:"last_login"` - Location string `json:"location"` - Login string `json:"login"` - LoginName string `json:"login_name"` - ProhibitLogin bool `json:"prohibit_login"` - Restricted bool `json:"restricted"` - SourceId int `json:"source_id"` - StarredReposCount int `json:"starred_repos_count"` - Username string `json:"username"` - Visibility string `json:"visibility"` - Website string `json:"website"` - } `json:"pusher"` - Ref string `json:"ref"` - Repository struct { - AllowFastForwardOnlyMerge bool `json:"allow_fast_forward_only_merge"` - AllowMergeCommits bool `json:"allow_merge_commits"` - AllowRebase bool `json:"allow_rebase"` - AllowRebaseExplicit bool `json:"allow_rebase_explicit"` - AllowRebaseUpdate bool `json:"allow_rebase_update"` - AllowSquashMerge bool `json:"allow_squash_merge"` - Archived bool `json:"archived"` - ArchivedAt time.Time `json:"archived_at"` - AvatarUrl string `json:"avatar_url"` - CloneUrl string `json:"clone_url"` - CreatedAt time.Time `json:"created_at"` - DefaultAllowMaintainerEdit bool `json:"default_allow_maintainer_edit"` - DefaultBranch string `json:"default_branch"` - DefaultDeleteBranchAfterMerge bool `json:"default_delete_branch_after_merge"` - DefaultMergeStyle string `json:"default_merge_style"` - Description string `json:"description"` - Empty bool `json:"empty"` - Fork bool `json:"fork"` - ForksCount int `json:"forks_count"` - FullName string `json:"full_name"` - HasActions bool `json:"has_actions"` - HasIssues bool `json:"has_issues"` - HasPackages bool `json:"has_packages"` - HasProjects bool `json:"has_projects"` - HasPullRequests bool `json:"has_pull_requests"` - HasReleases bool `json:"has_releases"` - HasWiki bool `json:"has_wiki"` - HtmlUrl string `json:"html_url"` - Id int `json:"id"` - IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` - Internal bool `json:"internal"` - InternalTracker struct { - AllowOnlyContributorsToTrackTime bool `json:"allow_only_contributors_to_track_time"` - EnableIssueDependencies bool `json:"enable_issue_dependencies"` - EnableTimeTracker bool `json:"enable_time_tracker"` - } `json:"internal_tracker"` - Language string `json:"language"` - LanguagesUrl string `json:"languages_url"` - Link string `json:"link"` - Mirror bool `json:"mirror"` - MirrorInterval string `json:"mirror_interval"` - MirrorUpdated time.Time `json:"mirror_updated"` - Name string `json:"name"` - ObjectFormatName string `json:"object_format_name"` - OpenIssuesCount int `json:"open_issues_count"` - OpenPrCounter int `json:"open_pr_counter"` - OriginalUrl string `json:"original_url"` - Owner struct { - Active bool `json:"active"` - AvatarUrl string `json:"avatar_url"` - Created time.Time `json:"created"` - Description string `json:"description"` - Email string `json:"email"` - FollowersCount int `json:"followers_count"` - FollowingCount int `json:"following_count"` - FullName string `json:"full_name"` - HtmlUrl string `json:"html_url"` - Id int `json:"id"` - IsAdmin bool `json:"is_admin"` - Language string `json:"language"` - LastLogin time.Time `json:"last_login"` - Location string `json:"location"` - Login string `json:"login"` - LoginName string `json:"login_name"` - ProhibitLogin bool `json:"prohibit_login"` - Restricted bool `json:"restricted"` - SourceId int `json:"source_id"` - StarredReposCount int `json:"starred_repos_count"` - Username string `json:"username"` - Visibility string `json:"visibility"` - Website string `json:"website"` - } `json:"owner"` - Parent interface{} `json:"parent"` - Permissions struct { - Admin bool `json:"admin"` - Pull bool `json:"pull"` - Push bool `json:"push"` - } `json:"permissions"` - Private bool `json:"private"` - ProjectsMode string `json:"projects_mode"` - ReleaseCounter int `json:"release_counter"` - RepoTransfer interface{} `json:"repo_transfer"` - Size int `json:"size"` - SshUrl string `json:"ssh_url"` - StarsCount int `json:"stars_count"` - Template bool `json:"template"` - UpdatedAt time.Time `json:"updated_at"` - Url string `json:"url"` - WatchersCount int `json:"watchers_count"` - Website string `json:"website"` - } `json:"repository"` - Sender struct { - Active bool `json:"active"` - AvatarUrl string `json:"avatar_url"` - Created time.Time `json:"created"` - Description string `json:"description"` - Email string `json:"email"` - FollowersCount int `json:"followers_count"` - FollowingCount int `json:"following_count"` - FullName string `json:"full_name"` - HtmlUrl string `json:"html_url"` - Id int `json:"id"` - IsAdmin bool `json:"is_admin"` - Language string `json:"language"` - LastLogin time.Time `json:"last_login"` - Location string `json:"location"` - Login string `json:"login"` - LoginName string `json:"login_name"` - ProhibitLogin bool `json:"prohibit_login"` - Restricted bool `json:"restricted"` - SourceId int `json:"source_id"` - StarredReposCount int `json:"starred_repos_count"` - Username string `json:"username"` - Visibility string `json:"visibility"` - Website string `json:"website"` - } `json:"sender"` - TotalCommits int `json:"total_commits"` - } `json:"event"` - EventPath string `json:"event_path"` - Workflow string `json:"workflow"` - RunId string `json:"run_id"` - RunNumber string `json:"run_number"` - Actor string `json:"actor"` - Repository string `json:"repository"` - EventName string `json:"event_name"` - Sha string `json:"sha"` - Ref string `json:"ref"` - RefName string `json:"ref_name"` - RefType string `json:"ref_type"` - HeadRef string `json:"head_ref"` - BaseRef string `json:"base_ref"` - Token string `json:"token"` - Workspace string `json:"workspace"` - Action string `json:"action"` - ActionPath string `json:"action_path"` - ActionRef string `json:"action_ref"` - ActionRepository string `json:"action_repository"` - Job string `json:"job"` - JobName string `json:"job_name"` - RepositoryOwner string `json:"repository_owner"` - RetentionDays string `json:"retention_days"` - RunnerPerflog string `json:"runner_perflog"` - RunnerTrackingId string `json:"runner_tracking_id"` - ServerUrl string `json:"server_url"` - ApiUrl string `json:"api_url"` - GraphqlUrl string `json:"graphql_url"` +func getExtraMsg(ctx *githubactions.GitHubContext) (result string) { + body, err := os.ReadFile(ctx.EventPath) + if err != nil { + slog.Error("读取文件失败", slog.Any("err", err), slog.String("path", ctx.EventPath)) + return + } + event := new(Event) + if err = json.Unmarshal(body, &event); err != nil { + slog.Error("解析json失败", slog.Any("err", err), slog.String("path", ctx.EventPath), slog.String("body", string(body))) + return + } + + result = "**更新内容:**\n%s\n\n[查看更新](%s)\t[查看Action](%s)" + + var commits []string + for _, v := range event.Commits { + commits = append(commits, fmt.Sprintf("- %s [%s](%s)", v.Message, v.Id, v.Url)) + } + + action := fmt.Sprintf("%s/%s/actions/runs/%d", ctx.ServerURL, ctx.Repository, ctx.RunNumber) + result = fmt.Sprintf(result, strings.Join(commits, "\n"), event.CompareUrl, action) + return +} + +type Event struct { + After string `json:"after"` + Before string `json:"before"` + Commits []struct { + Added []interface{} `json:"added"` + Author struct { + Email string `json:"email"` + Name string `json:"name"` + Username string `json:"username"` + } `json:"author"` + Committer struct { + Email string `json:"email"` + Name string `json:"name"` + Username string `json:"username"` + } `json:"committer"` + Id string `json:"id"` + Message string `json:"message"` + Modified []string `json:"modified"` + Removed []interface{} `json:"removed"` + Timestamp time.Time `json:"timestamp"` + Url string `json:"url"` + Verification interface{} `json:"verification"` + } `json:"commits"` + CompareUrl string `json:"compare_url"` + HeadCommit struct { + Added []interface{} `json:"added"` + Author struct { + Email string `json:"email"` + Name string `json:"name"` + Username string `json:"username"` + } `json:"author"` + Committer struct { + Email string `json:"email"` + Name string `json:"name"` + Username string `json:"username"` + } `json:"committer"` + Id string `json:"id"` + Message string `json:"message"` + Modified []string `json:"modified"` + Removed []interface{} `json:"removed"` + Timestamp time.Time `json:"timestamp"` + Url string `json:"url"` + Verification interface{} `json:"verification"` + } `json:"head_commit"` + Pusher struct { + Active bool `json:"active"` + AvatarUrl string `json:"avatar_url"` + Created time.Time `json:"created"` + Description string `json:"description"` + Email string `json:"email"` + FollowersCount int `json:"followers_count"` + FollowingCount int `json:"following_count"` + FullName string `json:"full_name"` + HtmlUrl string `json:"html_url"` + Id int `json:"id"` + IsAdmin bool `json:"is_admin"` + Language string `json:"language"` + LastLogin time.Time `json:"last_login"` + Location string `json:"location"` + Login string `json:"login"` + LoginName string `json:"login_name"` + ProhibitLogin bool `json:"prohibit_login"` + Restricted bool `json:"restricted"` + SourceId int `json:"source_id"` + StarredReposCount int `json:"starred_repos_count"` + Username string `json:"username"` + Visibility string `json:"visibility"` + Website string `json:"website"` + } `json:"pusher"` + Ref string `json:"ref"` + Repository struct { + AllowFastForwardOnlyMerge bool `json:"allow_fast_forward_only_merge"` + AllowMergeCommits bool `json:"allow_merge_commits"` + AllowRebase bool `json:"allow_rebase"` + AllowRebaseExplicit bool `json:"allow_rebase_explicit"` + AllowRebaseUpdate bool `json:"allow_rebase_update"` + AllowSquashMerge bool `json:"allow_squash_merge"` + Archived bool `json:"archived"` + ArchivedAt time.Time `json:"archived_at"` + AvatarUrl string `json:"avatar_url"` + CloneUrl string `json:"clone_url"` + CreatedAt time.Time `json:"created_at"` + DefaultAllowMaintainerEdit bool `json:"default_allow_maintainer_edit"` + DefaultBranch string `json:"default_branch"` + DefaultDeleteBranchAfterMerge bool `json:"default_delete_branch_after_merge"` + DefaultMergeStyle string `json:"default_merge_style"` + Description string `json:"description"` + Empty bool `json:"empty"` + Fork bool `json:"fork"` + ForksCount int `json:"forks_count"` + FullName string `json:"full_name"` + HasActions bool `json:"has_actions"` + HasIssues bool `json:"has_issues"` + HasPackages bool `json:"has_packages"` + HasProjects bool `json:"has_projects"` + HasPullRequests bool `json:"has_pull_requests"` + HasReleases bool `json:"has_releases"` + HasWiki bool `json:"has_wiki"` + HtmlUrl string `json:"html_url"` + Id int `json:"id"` + IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` + Internal bool `json:"internal"` + InternalTracker struct { + AllowOnlyContributorsToTrackTime bool `json:"allow_only_contributors_to_track_time"` + EnableIssueDependencies bool `json:"enable_issue_dependencies"` + EnableTimeTracker bool `json:"enable_time_tracker"` + } `json:"internal_tracker"` + Language string `json:"language"` + LanguagesUrl string `json:"languages_url"` + Link string `json:"link"` + Mirror bool `json:"mirror"` + MirrorInterval string `json:"mirror_interval"` + MirrorUpdated time.Time `json:"mirror_updated"` + Name string `json:"name"` + ObjectFormatName string `json:"object_format_name"` + OpenIssuesCount int `json:"open_issues_count"` + OpenPrCounter int `json:"open_pr_counter"` + OriginalUrl string `json:"original_url"` + Owner struct { + Active bool `json:"active"` + AvatarUrl string `json:"avatar_url"` + Created time.Time `json:"created"` + Description string `json:"description"` + Email string `json:"email"` + FollowersCount int `json:"followers_count"` + FollowingCount int `json:"following_count"` + FullName string `json:"full_name"` + HtmlUrl string `json:"html_url"` + Id int `json:"id"` + IsAdmin bool `json:"is_admin"` + Language string `json:"language"` + LastLogin time.Time `json:"last_login"` + Location string `json:"location"` + Login string `json:"login"` + LoginName string `json:"login_name"` + ProhibitLogin bool `json:"prohibit_login"` + Restricted bool `json:"restricted"` + SourceId int `json:"source_id"` + StarredReposCount int `json:"starred_repos_count"` + Username string `json:"username"` + Visibility string `json:"visibility"` + Website string `json:"website"` + } `json:"owner"` + Parent interface{} `json:"parent"` + Permissions struct { + Admin bool `json:"admin"` + Pull bool `json:"pull"` + Push bool `json:"push"` + } `json:"permissions"` + Private bool `json:"private"` + ProjectsMode string `json:"projects_mode"` + ReleaseCounter int `json:"release_counter"` + RepoTransfer interface{} `json:"repo_transfer"` + Size int `json:"size"` + SshUrl string `json:"ssh_url"` + StarsCount int `json:"stars_count"` + Template bool `json:"template"` + UpdatedAt time.Time `json:"updated_at"` + Url string `json:"url"` + WatchersCount int `json:"watchers_count"` + Website string `json:"website"` + } `json:"repository"` + Sender struct { + Active bool `json:"active"` + AvatarUrl string `json:"avatar_url"` + Created time.Time `json:"created"` + Description string `json:"description"` + Email string `json:"email"` + FollowersCount int `json:"followers_count"` + FollowingCount int `json:"following_count"` + FullName string `json:"full_name"` + HtmlUrl string `json:"html_url"` + Id int `json:"id"` + IsAdmin bool `json:"is_admin"` + Language string `json:"language"` + LastLogin time.Time `json:"last_login"` + Location string `json:"location"` + Login string `json:"login"` + LoginName string `json:"login_name"` + ProhibitLogin bool `json:"prohibit_login"` + Restricted bool `json:"restricted"` + SourceId int `json:"source_id"` + StarredReposCount int `json:"starred_repos_count"` + Username string `json:"username"` + Visibility string `json:"visibility"` + Website string `json:"website"` + } `json:"sender"` + TotalCommits int `json:"total_commits"` }