mirror of
https://github.com/thegeeklab/wp-git-action.git
synced 2024-11-24 22:50:39 +00:00
refactor: rework plugin structure and add pages action (#7)
This commit is contained in:
parent
686de4edfd
commit
e8c4aad467
@ -3,3 +3,4 @@ github
|
|||||||
url
|
url
|
||||||
gh
|
gh
|
||||||
drone-git-action
|
drone-git-action
|
||||||
|
rsync
|
||||||
|
@ -24,9 +24,12 @@ kind: pipeline
|
|||||||
name: default
|
name: default
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: commit artifact
|
- name: commit changelog
|
||||||
image: thegeeklab/drone-git-action
|
image: thegeeklab/drone-git-action
|
||||||
settings:
|
settings:
|
||||||
|
action:
|
||||||
|
- commit
|
||||||
|
- push
|
||||||
netrc_password: ghp_3LbMg9Kncpdkhjp3bh3dMnKNXLjVMTsXk4sM
|
netrc_password: ghp_3LbMg9Kncpdkhjp3bh3dMnKNXLjVMTsXk4sM
|
||||||
author_name: octobot
|
author_name: octobot
|
||||||
author_email: octobot@example.com
|
author_email: octobot@example.com
|
||||||
@ -41,6 +44,30 @@ steps:
|
|||||||
<!-- spellchecker-enable -->
|
<!-- spellchecker-enable -->
|
||||||
<!-- prettier-ignore-end -->
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
#### Publish GitHub pages
|
||||||
|
|
||||||
|
The plugin can be used to publish GitHub pages to the pages branch. Remember that the `pages` action cannot be combined with other actions.
|
||||||
|
|
||||||
|
```YAML
|
||||||
|
kind: pipeline
|
||||||
|
name: default
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: publish
|
||||||
|
image: thegeeklab/drone-git-action
|
||||||
|
settings:
|
||||||
|
action:
|
||||||
|
- pages
|
||||||
|
author_email: bot@thegeeklab.de
|
||||||
|
author_name: thegeeklab-bot
|
||||||
|
message: "update pages"
|
||||||
|
branch: gh-pages
|
||||||
|
pages_directory: docs/
|
||||||
|
netrc_password: ghp_3LbMg9Kncpdkhjp3bh3dMnKNXLjVMTsXk4sM
|
||||||
|
```
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
Build the binary with the following command:
|
Build the binary with the following command:
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
---
|
---
|
||||||
properties:
|
properties:
|
||||||
- name: actions
|
- name: action
|
||||||
description: "Git actions to to execute. Supported actions: `clone|commit|push`."
|
description: |
|
||||||
|
Git actions to be executed. Supported actions: `clone | commit | push | pages`. Specified actions are executed in the specified order
|
||||||
|
|
||||||
|
- **clone:** Clones the repository in `remote` and checks out the `branch` to `path`.
|
||||||
|
- **commit:** Adds a commit to the default drone repository or the repository in `remote`.
|
||||||
|
- **push:** Pushes all commits to the default drone repository or the repository set in `remote`.
|
||||||
|
- **pages:** The `pages` action is a special action that cannot be combined with other actions. It is intended for use for
|
||||||
|
GitHub pages. It synchronizes the contents of `pages_directory` with the target `branch` using `rsync` and pushes the changes automatically.
|
||||||
required: true
|
required: true
|
||||||
type: list
|
type: list
|
||||||
|
|
||||||
@ -43,7 +50,7 @@ properties:
|
|||||||
type: string
|
type: string
|
||||||
|
|
||||||
- name: path
|
- name: path
|
||||||
description: Path to git repository.
|
description: Path to clone the git repository.
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
- name: message
|
- name: message
|
||||||
@ -75,3 +82,17 @@ properties:
|
|||||||
description: Bypass the pre-commit and commit-msg hooks.
|
description: Bypass the pre-commit and commit-msg hooks.
|
||||||
defaultvalue: false
|
defaultvalue: false
|
||||||
type: bool
|
type: bool
|
||||||
|
|
||||||
|
- name: pages_directory
|
||||||
|
description: Source directory to be synchronized with the pages `branch`.
|
||||||
|
defaultvalue: docs/
|
||||||
|
type: string
|
||||||
|
|
||||||
|
- name: pages_exclude
|
||||||
|
description: Files or directories to exclude from the rsync command.
|
||||||
|
type: list
|
||||||
|
|
||||||
|
- name: pages_delete
|
||||||
|
description: When set to `true`, the `--delete` flag is added to the rsync command to remove files from the `branch` that do not exist in the `pages_directory` either.
|
||||||
|
defaultvalue: true
|
||||||
|
type: bool
|
||||||
|
@ -9,33 +9,32 @@ import (
|
|||||||
func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
||||||
return []cli.Flag{
|
return []cli.Flag{
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "actions",
|
Name: "action",
|
||||||
Usage: "git actions to to execute",
|
Usage: "git action to to execute",
|
||||||
EnvVars: []string{"PLUGIN_ACTIONS"},
|
EnvVars: []string{"PLUGIN_ACTION"},
|
||||||
Destination: &settings.Actions,
|
Destination: &settings.Action,
|
||||||
Required: true,
|
Required: true,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
|
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "commit-author-name",
|
Name: "author-name",
|
||||||
Usage: "git author name",
|
Usage: "git author name",
|
||||||
EnvVars: []string{"PLUGIN_AUTHOR_NAME", "DRONE_COMMIT_AUTHOR"},
|
EnvVars: []string{"PLUGIN_AUTHOR_NAME", "DRONE_COMMIT_AUTHOR"},
|
||||||
Destination: &settings.Commit.Author.Name,
|
Destination: &settings.Repo.Author.Name,
|
||||||
Required: true,
|
Required: true,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "commit-author-email",
|
Name: "author-email",
|
||||||
Usage: "git author email",
|
Usage: "git author email",
|
||||||
EnvVars: []string{"PLUGIN_AUTHOR_EMAIL", "DRONE_COMMIT_AUTHOR_EMAIL"},
|
EnvVars: []string{"PLUGIN_AUTHOR_EMAIL", "DRONE_COMMIT_AUTHOR_EMAIL"},
|
||||||
Destination: &settings.Commit.Author.Email,
|
Destination: &settings.Repo.Author.Email,
|
||||||
Required: true,
|
Required: true,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
|
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "netrc-machine",
|
Name: "netrc.machine",
|
||||||
Usage: "netrc remote machine name",
|
Usage: "netrc remote machine name",
|
||||||
EnvVars: []string{"PLUGIN_NETRC_MACHINE", "DRONE_NETRC_MACHINE"},
|
EnvVars: []string{"PLUGIN_NETRC_MACHINE", "DRONE_NETRC_MACHINE"},
|
||||||
Destination: &settings.Netrc.Machine,
|
Destination: &settings.Netrc.Machine,
|
||||||
@ -43,7 +42,7 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
|||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "netrc-username",
|
Name: "netrc.username",
|
||||||
Usage: "netrc login user on the remote machine",
|
Usage: "netrc login user on the remote machine",
|
||||||
EnvVars: []string{"PLUGIN_NETRC_USERNAME", "DRONE_NETRC_USERNAME"},
|
EnvVars: []string{"PLUGIN_NETRC_USERNAME", "DRONE_NETRC_USERNAME"},
|
||||||
Destination: &settings.Netrc.Login,
|
Destination: &settings.Netrc.Login,
|
||||||
@ -51,7 +50,7 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
|||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "netrc-password",
|
Name: "netrc.password",
|
||||||
Usage: "netrc login password on the remote machine",
|
Usage: "netrc login password on the remote machine",
|
||||||
EnvVars: []string{"PLUGIN_NETRC_PASSWORD", "DRONE_NETRC_PASSWORD"},
|
EnvVars: []string{"PLUGIN_NETRC_PASSWORD", "DRONE_NETRC_PASSWORD"},
|
||||||
Destination: &settings.Netrc.Password,
|
Destination: &settings.Netrc.Password,
|
||||||
@ -68,41 +67,38 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
|||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "remote",
|
Name: "remote",
|
||||||
Usage: "url of the remote repository",
|
Usage: "url of the remote repository",
|
||||||
EnvVars: []string{"PLUGIN_REMOTE"},
|
EnvVars: []string{"PLUGIN_REMOTE", "DRONE_REMOTE_URL"},
|
||||||
Destination: &settings.Remote,
|
Destination: &settings.Repo.RemoteURL,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "branch",
|
Name: "branch",
|
||||||
Usage: "name of the git branch",
|
Usage: "name of the git source branch",
|
||||||
EnvVars: []string{"PLUGIN_BRANCH"},
|
EnvVars: []string{"PLUGIN_BRANCH"},
|
||||||
Destination: &settings.Branch,
|
Destination: &settings.Repo.Branch,
|
||||||
Value: "main",
|
Value: "main",
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
|
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "path",
|
Name: "path",
|
||||||
Usage: "path to git repository",
|
Usage: "path to clone git repository",
|
||||||
EnvVars: []string{"PLUGIN_PATH"},
|
EnvVars: []string{"PLUGIN_PATH"},
|
||||||
Destination: &settings.Path,
|
Destination: &settings.Repo.WorkDir,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
|
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "message",
|
Name: "commit-message",
|
||||||
Usage: "commit message",
|
Usage: "commit message",
|
||||||
EnvVars: []string{"PLUGIN_MESSAGE"},
|
EnvVars: []string{"PLUGIN_MESSAGE"},
|
||||||
Destination: &settings.Message,
|
Destination: &settings.Repo.CommitMsg,
|
||||||
Value: "[skip ci] commit dirty state",
|
Value: "[skip ci] commit dirty state",
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
|
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "force",
|
Name: "force-push",
|
||||||
Usage: "enable force push to remote repository",
|
Usage: "enable force push to remote repository",
|
||||||
EnvVars: []string{"PLUGIN_FORCE"},
|
EnvVars: []string{"PLUGIN_FORCE"},
|
||||||
Destination: &settings.Force,
|
Destination: &settings.Repo.ForcePush,
|
||||||
Value: false,
|
Value: false,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
@ -110,7 +106,7 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
|||||||
Name: "followtags",
|
Name: "followtags",
|
||||||
Usage: "follow tags for pushes to remote repository",
|
Usage: "follow tags for pushes to remote repository",
|
||||||
EnvVars: []string{"PLUGIN_FOLLOWTAGS"},
|
EnvVars: []string{"PLUGIN_FOLLOWTAGS"},
|
||||||
Destination: &settings.FollowTags,
|
Destination: &settings.Repo.PushFollowTags,
|
||||||
Value: false,
|
Value: false,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
@ -118,7 +114,7 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
|||||||
Name: "insecure-ssl-verify",
|
Name: "insecure-ssl-verify",
|
||||||
Usage: "set SSL verification of the remote machine",
|
Usage: "set SSL verification of the remote machine",
|
||||||
EnvVars: []string{"PLUGIN_INSECURE_SSL_VERIFY"},
|
EnvVars: []string{"PLUGIN_INSECURE_SSL_VERIFY"},
|
||||||
Destination: &settings.InsecureSSLVerify,
|
Destination: &settings.Repo.InsecureSSLVerify,
|
||||||
Value: false,
|
Value: false,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
@ -126,7 +122,7 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
|||||||
Name: "empty-commit",
|
Name: "empty-commit",
|
||||||
Usage: "allow empty commits",
|
Usage: "allow empty commits",
|
||||||
EnvVars: []string{"PLUGIN_EMPTY_COMMIT"},
|
EnvVars: []string{"PLUGIN_EMPTY_COMMIT"},
|
||||||
Destination: &settings.EmptyCommit,
|
Destination: &settings.Repo.EmptyCommit,
|
||||||
Value: false,
|
Value: false,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
@ -134,9 +130,32 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
|||||||
Name: "no-verify",
|
Name: "no-verify",
|
||||||
Usage: "bypass the pre-commit and commit-msg hooks",
|
Usage: "bypass the pre-commit and commit-msg hooks",
|
||||||
EnvVars: []string{"PLUGIN_NO_VERIFY"},
|
EnvVars: []string{"PLUGIN_NO_VERIFY"},
|
||||||
Destination: &settings.NoVerify,
|
Destination: &settings.Repo.NoVerify,
|
||||||
Value: false,
|
Value: false,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "pages.directory",
|
||||||
|
Usage: "source directory for pages sync",
|
||||||
|
EnvVars: []string{"PLUGIN_PAGES_DIRECTORY"},
|
||||||
|
Destination: &settings.Pages.Directory,
|
||||||
|
Value: "docs/",
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringSliceFlag{
|
||||||
|
Name: "pages.exclude",
|
||||||
|
Usage: "exclude flag added to pages rsnyc command",
|
||||||
|
EnvVars: []string{"PLUGIN_PAGES_EXCLUDE"},
|
||||||
|
Destination: &settings.Pages.Exclude,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "pages.delete",
|
||||||
|
Usage: "delete flag added to pages rsync command",
|
||||||
|
EnvVars: []string{"PLUGIN_PAGES_DELETE"},
|
||||||
|
Destination: &settings.Pages.Delete,
|
||||||
|
Value: true,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ LABEL org.opencontainers.image.url="https://github.com/thegeeklab/drone-git-acti
|
|||||||
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/drone-git-action"
|
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/drone-git-action"
|
||||||
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/drone-git-action"
|
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/drone-git-action"
|
||||||
|
|
||||||
RUN apk --update add --no-cache git && \
|
RUN apk --update add --no-cache git rsync && \
|
||||||
rm -rf /var/cache/apk/* && \
|
rm -rf /var/cache/apk/* && \
|
||||||
rm -rf /tmp/*
|
rm -rf /tmp/*
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ LABEL org.opencontainers.image.url="https://github.com/thegeeklab/drone-git-acti
|
|||||||
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/drone-git-action"
|
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/drone-git-action"
|
||||||
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/drone-git-action"
|
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/drone-git-action"
|
||||||
|
|
||||||
RUN apk --update add --no-cache git && \
|
RUN apk --update add --no-cache git rsync && \
|
||||||
rm -rf /var/cache/apk/* && \
|
rm -rf /var/cache/apk/* && \
|
||||||
rm -rf /tmp/*
|
rm -rf /tmp/*
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ LABEL org.opencontainers.image.url="https://github.com/thegeeklab/drone-git-acti
|
|||||||
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/drone-git-action"
|
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/drone-git-action"
|
||||||
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/drone-git-action"
|
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/drone-git-action"
|
||||||
|
|
||||||
RUN apk --update add --no-cache git && \
|
RUN apk --update add --no-cache git rsync && \
|
||||||
rm -rf /var/cache/apk/* && \
|
rm -rf /var/cache/apk/* && \
|
||||||
rm -rf /tmp/*
|
rm -rf /tmp/*
|
||||||
|
|
||||||
|
35
git/clone.go
Normal file
35
git/clone.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FetchSource fetches the source from remote.
|
||||||
|
func FetchSource(repo Repository) *exec.Cmd {
|
||||||
|
cmd := exec.Command(
|
||||||
|
"git",
|
||||||
|
"fetch",
|
||||||
|
"origin",
|
||||||
|
fmt.Sprintf("+%s:", repo.Branch),
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckoutHead handles branch checkout.
|
||||||
|
func CheckoutHead(repo Repository) *exec.Cmd {
|
||||||
|
cmd := exec.Command(
|
||||||
|
"git",
|
||||||
|
"checkout",
|
||||||
|
"-qf",
|
||||||
|
repo.Branch,
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
@ -1,74 +1,89 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ForceAdd forces the addition of all dirty files.
|
// ForceAdd forces the addition of all dirty files.
|
||||||
func ForceAdd() *exec.Cmd {
|
func ForceAdd(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"add",
|
"add",
|
||||||
"--all",
|
"--all",
|
||||||
"--force")
|
"--force",
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add updates the index to match the working tree.
|
// Add updates the index to match the working tree.
|
||||||
func Add() *exec.Cmd {
|
func Add(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"add",
|
"add",
|
||||||
"--all")
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
if repo.Add != "" {
|
||||||
|
cmd.Args = append(cmd.Args, repo.Add)
|
||||||
|
} else {
|
||||||
|
cmd.Args = append(cmd.Args, "--all")
|
||||||
|
}
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestCleanTree returns non-zero if diff between index and local repository
|
// TestCleanTree returns non-zero if diff between index and local repository
|
||||||
func TestCleanTree() *exec.Cmd {
|
func TestCleanTree(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"diff-index",
|
"diff-index",
|
||||||
"--quiet",
|
"--quiet",
|
||||||
"HEAD",
|
"HEAD",
|
||||||
"--ignore-submodules")
|
"--ignore-submodules",
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmptyCommit simply create an empty commit
|
// EmptyCommit simply create an empty commit
|
||||||
func EmptyCommit(msg string, noVerify bool) *exec.Cmd {
|
func EmptyCommit(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"commit",
|
"commit",
|
||||||
"--allow-empty",
|
"--allow-empty",
|
||||||
"-m",
|
"-m",
|
||||||
msg,
|
repo.CommitMsg,
|
||||||
)
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
if noVerify {
|
if repo.NoVerify {
|
||||||
cmd.Args = append(
|
cmd.Args = append(cmd.Args, "--no-verify")
|
||||||
cmd.Args,
|
|
||||||
"--no-verify")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForceCommit commits every change while skipping CI.
|
// ForceCommit commits every change while skipping CI.
|
||||||
func ForceCommit(msg string, noVerify bool) *exec.Cmd {
|
func ForceCommit(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"commit",
|
"commit",
|
||||||
"-m",
|
"-m",
|
||||||
msg,
|
repo.CommitMsg,
|
||||||
)
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
if noVerify {
|
if repo.NoVerify {
|
||||||
cmd.Args = append(
|
cmd.Args = append(cmd.Args, "--no-verify")
|
||||||
cmd.Args,
|
|
||||||
"--no-verify")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -1,42 +1,67 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetUserEmail sets the global git author email.
|
// repoUserEmail sets the global git author email.
|
||||||
func SetUserEmail(email string) *exec.Cmd {
|
func ConfigAutocorrect(repo Repository) *exec.Cmd {
|
||||||
|
cmd := exec.Command(
|
||||||
|
"git",
|
||||||
|
"config",
|
||||||
|
"--local",
|
||||||
|
"help.autocorrect",
|
||||||
|
repo.Autocorrect,
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// repoUserEmail sets the global git author email.
|
||||||
|
func ConfigUserEmail(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"config",
|
"config",
|
||||||
"--local",
|
"--local",
|
||||||
"user.email",
|
"user.email",
|
||||||
email)
|
repo.Author.Email,
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetUserName sets the global git author name.
|
// repoUserName sets the global git author name.
|
||||||
func SetUserName(author string) *exec.Cmd {
|
func ConfigUserName(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"config",
|
"config",
|
||||||
"--local",
|
"--local",
|
||||||
"user.name",
|
"user.name",
|
||||||
author)
|
repo.Author.Name,
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSSLSkipVerify disables globally the git ssl verification.
|
// repoSSLVerify disables globally the git ssl verification.
|
||||||
func SetSSLVerify(sslVerify bool) *exec.Cmd {
|
func ConfigSSLVerify(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"config",
|
"config",
|
||||||
"--local",
|
"--local",
|
||||||
"http.sslVerify",
|
"http.sslVerify",
|
||||||
strconv.FormatBool(sslVerify))
|
strconv.FormatBool(repo.SSLVerify),
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -1,52 +1,59 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RemoteRemove drops the defined remote from a git repo.
|
// RemoteRemove drops the defined remote from a git repo.
|
||||||
func RemoteRemove(name string) *exec.Cmd {
|
func RemoteRemove(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"remote",
|
"remote",
|
||||||
"rm",
|
"rm",
|
||||||
name)
|
repo.RemoteName,
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteAdd adds an additional remote to a git repo.
|
// RemoteAdd adds an additional remote to a git repo.
|
||||||
func RemoteAdd(name, url string) *exec.Cmd {
|
func RemoteAdd(repo Repository) *exec.Cmd {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"remote",
|
"remote",
|
||||||
"add",
|
"add",
|
||||||
name,
|
repo.RemoteName,
|
||||||
url)
|
repo.RemoteURL,
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemotePush pushs the changes from the local head to a remote branch.
|
// RemotePush pushs the changes from the local head to a remote branch.
|
||||||
func RemotePush(remote, branch string, force, followtags bool) *exec.Cmd {
|
func RemotePush(repo Repository) *exec.Cmd {
|
||||||
return RemotePushNamedBranch(remote, "HEAD", branch, force, followtags)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemotePushNamedBranch puchs changes from a local to a remote branch.
|
|
||||||
func RemotePushNamedBranch(remote, localbranch, branch string, force, followtags bool) *exec.Cmd {
|
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"git",
|
"git",
|
||||||
"push",
|
"push",
|
||||||
remote,
|
repo.RemoteName,
|
||||||
localbranch+":"+branch)
|
fmt.Sprintf("HEAD:%s", repo.Branch),
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
if force {
|
if repo.ForcePush {
|
||||||
cmd.Args = append(
|
cmd.Args = append(
|
||||||
cmd.Args,
|
cmd.Args,
|
||||||
"--force")
|
"--force",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if followtags {
|
if repo.PushFollowTags {
|
||||||
cmd.Args = append(
|
cmd.Args = append(
|
||||||
cmd.Args,
|
cmd.Args,
|
||||||
"--follow-tags")
|
"--follow-tags")
|
||||||
|
42
git/status.go
Normal file
42
git/status.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Status(repo Repository) *exec.Cmd {
|
||||||
|
cmd := exec.Command(
|
||||||
|
"git",
|
||||||
|
"status",
|
||||||
|
"--porcelain",
|
||||||
|
)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsDirty(repo Repository) bool {
|
||||||
|
res := bytes.NewBufferString("")
|
||||||
|
|
||||||
|
cmd := Status(repo)
|
||||||
|
cmd.Dir = repo.WorkDir
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
cmd.Stdout = res
|
||||||
|
cmd.Stderr = res
|
||||||
|
|
||||||
|
err := runCommand(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.Len() > 0 {
|
||||||
|
fmt.Print(res.String())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
27
git/type.go
Normal file
27
git/type.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
type Author struct {
|
||||||
|
Name string
|
||||||
|
Email string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Repository struct {
|
||||||
|
RemoteName string
|
||||||
|
RemoteURL string
|
||||||
|
Branch string
|
||||||
|
|
||||||
|
Add string
|
||||||
|
CommitMsg string
|
||||||
|
|
||||||
|
Autocorrect string
|
||||||
|
NoVerify bool
|
||||||
|
InsecureSSLVerify bool
|
||||||
|
EmptyCommit bool
|
||||||
|
PushFollowTags bool
|
||||||
|
ForcePush bool
|
||||||
|
SSLVerify bool
|
||||||
|
WorkDir string
|
||||||
|
InitExists bool
|
||||||
|
|
||||||
|
Author Author
|
||||||
|
}
|
32
git/utils.go
32
git/utils.go
@ -3,8 +3,10 @@ package git
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const netrcFile = `
|
const netrcFile = `
|
||||||
@ -27,17 +29,13 @@ func WriteSSHKey(privateKey string) error {
|
|||||||
home = currentUser.HomeDir
|
home = currentUser.HomeDir
|
||||||
}
|
}
|
||||||
|
|
||||||
sshpath := filepath.Join(
|
sshpath := filepath.Join(home, ".ssh")
|
||||||
home,
|
|
||||||
".ssh")
|
|
||||||
|
|
||||||
if err := os.MkdirAll(sshpath, 0o700); err != nil {
|
if err := os.MkdirAll(sshpath, 0o700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
confpath := filepath.Join(
|
confpath := filepath.Join(sshpath, "config")
|
||||||
sshpath,
|
|
||||||
"config")
|
|
||||||
|
|
||||||
if err := os.WriteFile(
|
if err := os.WriteFile(
|
||||||
confpath,
|
confpath,
|
||||||
@ -47,10 +45,7 @@ func WriteSSHKey(privateKey string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privpath := filepath.Join(
|
privpath := filepath.Join(sshpath, "id_rsa")
|
||||||
sshpath,
|
|
||||||
"id_rsa",
|
|
||||||
)
|
|
||||||
|
|
||||||
if err := os.WriteFile(
|
if err := os.WriteFile(
|
||||||
privpath,
|
privpath,
|
||||||
@ -89,3 +84,20 @@ func WriteNetrc(machine, login, password string) error {
|
|||||||
0o600,
|
0o600,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func trace(cmd *exec.Cmd) {
|
||||||
|
fmt.Fprintf(os.Stdout, "+ %s\n", strings.Join(cmd.Args, " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCommand(cmd *exec.Cmd) error {
|
||||||
|
if cmd.Stdout == nil {
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.Stderr == nil {
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
trace(cmd)
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
111
plugin/git.go
111
plugin/git.go
@ -1,111 +0,0 @@
|
|||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/drone-git-action/git"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InitRepo initializes the repository.
|
|
||||||
func (p Plugin) initRepo() error {
|
|
||||||
path := filepath.Join(p.settings.Path, ".git")
|
|
||||||
if err := os.MkdirAll(p.settings.Path, os.ModePerm); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.Chdir(p.settings.Path); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if isDirEmpty(path) {
|
|
||||||
return execute(exec.Command(
|
|
||||||
"git",
|
|
||||||
"init",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddRemote adds a remote to repository.
|
|
||||||
func (p Plugin) addRemote() error {
|
|
||||||
if p.settings.Remote != "" {
|
|
||||||
if err := execute(git.RemoteAdd("origin", p.settings.Remote)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchSource fetches the source from remote.
|
|
||||||
func (p Plugin) fetchSource() error {
|
|
||||||
return execute(exec.Command(
|
|
||||||
"git",
|
|
||||||
"fetch",
|
|
||||||
"origin",
|
|
||||||
fmt.Sprintf("+%s:", p.settings.Branch),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckoutHead handles branch checkout.
|
|
||||||
func (p Plugin) checkoutHead() error {
|
|
||||||
return execute(exec.Command(
|
|
||||||
"git",
|
|
||||||
"checkout",
|
|
||||||
"-qf",
|
|
||||||
p.settings.Branch,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleClone clones remote.
|
|
||||||
func (p Plugin) handleClone() error {
|
|
||||||
if err := p.addRemote(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := p.fetchSource(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := p.checkoutHead(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleCommit commits changes locally.
|
|
||||||
func (p Plugin) handleCommit() error {
|
|
||||||
if err := execute(git.Add()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := execute(git.TestCleanTree()); err != nil {
|
|
||||||
if err := execute(git.ForceCommit(p.settings.Message, p.settings.NoVerify)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if p.settings.EmptyCommit {
|
|
||||||
if err := execute(git.EmptyCommit(p.settings.Message, p.settings.NoVerify)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandlePush pushs changes to remote.
|
|
||||||
func (p Plugin) handlePush() error {
|
|
||||||
return execute(git.RemotePushNamedBranch(
|
|
||||||
"origin",
|
|
||||||
p.settings.Branch,
|
|
||||||
p.settings.Branch,
|
|
||||||
p.settings.Force,
|
|
||||||
p.settings.FollowTags,
|
|
||||||
))
|
|
||||||
}
|
|
184
plugin/impl.go
184
plugin/impl.go
@ -3,6 +3,8 @@ package plugin
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/thegeeklab/drone-git-action/git"
|
"github.com/thegeeklab/drone-git-action/git"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@ -14,37 +16,38 @@ type Netrc struct {
|
|||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Commit struct {
|
type Pages struct {
|
||||||
Author Author
|
Directory string
|
||||||
}
|
Exclude cli.StringSlice
|
||||||
|
Delete bool
|
||||||
type Author struct {
|
|
||||||
Name string
|
|
||||||
Email string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Settings for the Plugin.
|
// Settings for the Plugin.
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Actions cli.StringSlice
|
Action cli.StringSlice
|
||||||
SSHKey string
|
SSHKey string
|
||||||
Remote string
|
|
||||||
Branch string
|
|
||||||
Path string
|
|
||||||
Message string
|
|
||||||
Force bool
|
|
||||||
FollowTags bool
|
|
||||||
InsecureSSLVerify bool
|
|
||||||
EmptyCommit bool
|
|
||||||
NoVerify bool
|
|
||||||
|
|
||||||
Netrc Netrc
|
Netrc Netrc
|
||||||
Commit Commit
|
Pages Pages
|
||||||
Author Author
|
Repo git.Repository
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate handles the settings validation of the plugin.
|
// Validate handles the settings validation of the plugin.
|
||||||
func (p *Plugin) Validate() error {
|
func (p *Plugin) Validate() error {
|
||||||
for _, action := range p.settings.Actions.Value() {
|
var err error
|
||||||
|
|
||||||
|
p.settings.Repo.Autocorrect = "never"
|
||||||
|
p.settings.Repo.RemoteName = "origin"
|
||||||
|
p.settings.Repo.Add = ""
|
||||||
|
|
||||||
|
if p.settings.Repo.WorkDir == "" {
|
||||||
|
p.settings.Repo.WorkDir, err = os.Getwd()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, action := range p.settings.Action.Value() {
|
||||||
switch action {
|
switch action {
|
||||||
case "clone":
|
case "clone":
|
||||||
continue
|
continue
|
||||||
@ -52,7 +55,30 @@ func (p *Plugin) Validate() error {
|
|||||||
continue
|
continue
|
||||||
case "push":
|
case "push":
|
||||||
if p.settings.SSHKey == "" && p.settings.Netrc.Password == "" {
|
if p.settings.SSHKey == "" && p.settings.Netrc.Password == "" {
|
||||||
return fmt.Errorf("either SSH key or netrc password are required")
|
return fmt.Errorf("either SSH key or netrc password is required")
|
||||||
|
}
|
||||||
|
case "pages":
|
||||||
|
p.settings.Pages.Directory = filepath.Join(p.settings.Repo.WorkDir, p.settings.Pages.Directory)
|
||||||
|
p.settings.Repo.WorkDir = filepath.Join(p.settings.Repo.WorkDir, ".tmp")
|
||||||
|
|
||||||
|
if _, err := os.Stat(p.settings.Pages.Directory); os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("pages directory '%s' must exist", p.settings.Pages.Directory)
|
||||||
|
}
|
||||||
|
|
||||||
|
if info, _ := os.Stat(p.settings.Pages.Directory); !info.IsDir() {
|
||||||
|
return fmt.Errorf("pages directory '%s' is not a directory", p.settings.Pages.Directory)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.settings.SSHKey == "" && p.settings.Netrc.Password == "" {
|
||||||
|
return fmt.Errorf("either SSH key or netrc password is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.settings.Pages.Directory == "" {
|
||||||
|
return fmt.Errorf("pages source directory needs to be set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(p.settings.Action.Value()) > 1 {
|
||||||
|
return fmt.Errorf("pages action can not be combined with other actions")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown action %s", action)
|
return fmt.Errorf("unknown action %s", action)
|
||||||
@ -81,19 +107,20 @@ func (p *Plugin) Execute() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.settings.Path != "" {
|
if err := p.initRepo(); err != nil {
|
||||||
if err := p.initRepo(); err != nil {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := git.SetUserName(p.settings.Commit.Author.Name).Run(); err != nil {
|
if err := git.ConfigAutocorrect(p.settings.Repo).Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := git.SetUserEmail(p.settings.Commit.Author.Email).Run(); err != nil {
|
if err := git.ConfigUserName(p.settings.Repo).Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := git.SetSSLVerify(p.settings.InsecureSSLVerify).Run(); err != nil {
|
if err := git.ConfigUserEmail(p.settings.Repo).Run(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := git.ConfigSSLVerify(p.settings.Repo).Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +134,7 @@ func (p *Plugin) Execute() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, action := range p.settings.Actions.Value() {
|
for _, action := range p.settings.Action.Value() {
|
||||||
switch action {
|
switch action {
|
||||||
case "clone":
|
case "clone":
|
||||||
if err := p.handleClone(); err != nil {
|
if err := p.handleClone(); err != nil {
|
||||||
@ -121,8 +148,103 @@ func (p *Plugin) Execute() error {
|
|||||||
if err := p.handlePush(); err != nil {
|
if err := p.handlePush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case "pages":
|
||||||
|
if err := p.handlePages(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitRepo initializes the repository.
|
||||||
|
func (p *Plugin) initRepo() error {
|
||||||
|
path := filepath.Join(p.settings.Repo.WorkDir, ".git")
|
||||||
|
if err := os.MkdirAll(p.settings.Repo.WorkDir, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||||
|
p.settings.Repo.InitExists = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(
|
||||||
|
"git",
|
||||||
|
"init",
|
||||||
|
)
|
||||||
|
cmd.Dir = p.settings.Repo.WorkDir
|
||||||
|
|
||||||
|
return execute(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleClone clones remote.
|
||||||
|
func (p *Plugin) handleClone() error {
|
||||||
|
if p.settings.Repo.InitExists {
|
||||||
|
return fmt.Errorf("destination '%s' already exists and is not an empty directory", p.settings.Repo.WorkDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.settings.Repo.RemoteURL != "" {
|
||||||
|
if err := execute(git.RemoteAdd(p.settings.Repo)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := execute(git.FetchSource(p.settings.Repo)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := execute(git.CheckoutHead(p.settings.Repo)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCommit commits changes locally.
|
||||||
|
func (p *Plugin) handleCommit() error {
|
||||||
|
if err := execute(git.Add(p.settings.Repo)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := execute(git.TestCleanTree(p.settings.Repo)); err != nil {
|
||||||
|
if err := execute(git.ForceCommit(p.settings.Repo)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if p.settings.Repo.EmptyCommit {
|
||||||
|
if err := execute(git.EmptyCommit(p.settings.Repo)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandlePush pushs changes to remote.
|
||||||
|
func (p *Plugin) handlePush() error {
|
||||||
|
return execute(git.RemotePush(p.settings.Repo))
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandlePages syncs, commits and pushes the changes from the pages directory to the pages branch.
|
||||||
|
func (p *Plugin) handlePages() error {
|
||||||
|
defer os.RemoveAll(p.settings.Repo.WorkDir)
|
||||||
|
|
||||||
|
if err := p.handleClone(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := execute(
|
||||||
|
rsyncDirectories(p.settings.Pages, p.settings.Repo),
|
||||||
|
); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := p.handleCommit(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.handlePush()
|
||||||
|
}
|
||||||
|
@ -2,10 +2,11 @@ package plugin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/thegeeklab/drone-git-action/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
// helper function to simply wrap os execte command.
|
// helper function to simply wrap os execte command.
|
||||||
@ -19,15 +20,39 @@ func execute(cmd *exec.Cmd) error {
|
|||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function returns true if directory dir is empty.
|
func rsyncDirectories(pages Pages, repo git.Repository) *exec.Cmd {
|
||||||
func isDirEmpty(dir string) bool {
|
args := []string{
|
||||||
f, err := os.Open(dir)
|
"-r",
|
||||||
if err != nil {
|
"--exclude",
|
||||||
return true
|
".git",
|
||||||
}
|
}
|
||||||
|
|
||||||
defer f.Close()
|
for _, item := range pages.Exclude.Value() {
|
||||||
|
args = append(
|
||||||
|
args,
|
||||||
|
"--exclude",
|
||||||
|
item,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
_, err = f.Readdir(1)
|
if pages.Delete {
|
||||||
return err == io.EOF
|
args = append(
|
||||||
|
args,
|
||||||
|
"--delete",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(
|
||||||
|
args,
|
||||||
|
".",
|
||||||
|
repo.WorkDir,
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd := exec.Command(
|
||||||
|
"rsync",
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
cmd.Dir = pages.Directory
|
||||||
|
|
||||||
|
return cmd
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user