mirror of
https://github.com/thegeeklab/wp-git-clone.git
synced 2024-11-21 14:10:38 +00:00
initial commit
This commit is contained in:
commit
378831f327
4
.dictionary
Normal file
4
.dictionary
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
userid
|
||||||
|
url
|
||||||
|
roomid
|
||||||
|
wp-git-clone
|
71
.github/settings.yml
vendored
Normal file
71
.github/settings.yml
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
repository:
|
||||||
|
name: wp-git-clone
|
||||||
|
description: Woodpecker CI plugin to clone git repositories
|
||||||
|
homepage: https://woodpecker-plugins.geekdocs.de/plugins/wp-git-clone
|
||||||
|
topics: woodpecker-ci, woodpecker, woodpecker-plugin
|
||||||
|
|
||||||
|
private: false
|
||||||
|
has_issues: true
|
||||||
|
has_wiki: false
|
||||||
|
has_downloads: true
|
||||||
|
|
||||||
|
default_branch: main
|
||||||
|
|
||||||
|
allow_squash_merge: true
|
||||||
|
allow_merge_commit: true
|
||||||
|
allow_rebase_merge: true
|
||||||
|
|
||||||
|
labels:
|
||||||
|
- name: bug
|
||||||
|
color: d73a4a
|
||||||
|
description: Something isn't working
|
||||||
|
- name: documentation
|
||||||
|
color: 0075ca
|
||||||
|
description: Improvements or additions to documentation
|
||||||
|
- name: duplicate
|
||||||
|
color: cfd3d7
|
||||||
|
description: This issue or pull request already exists
|
||||||
|
- name: enhancement
|
||||||
|
color: a2eeef
|
||||||
|
description: New feature or request
|
||||||
|
- name: good first issue
|
||||||
|
color: 7057ff
|
||||||
|
description: Good for newcomers
|
||||||
|
- name: help wanted
|
||||||
|
color: 008672
|
||||||
|
description: Extra attention is needed
|
||||||
|
- name: invalid
|
||||||
|
color: e4e669
|
||||||
|
description: This doesn't seem right
|
||||||
|
- name: question
|
||||||
|
color: d876e3
|
||||||
|
description: Further information is requested
|
||||||
|
- name: wontfix
|
||||||
|
color: ffffff
|
||||||
|
description: This will not be worked on
|
||||||
|
|
||||||
|
branches:
|
||||||
|
- name: main
|
||||||
|
protection:
|
||||||
|
required_pull_request_reviews: null
|
||||||
|
required_status_checks:
|
||||||
|
strict: false
|
||||||
|
contexts:
|
||||||
|
- ci/woodpecker/pr/test
|
||||||
|
- ci/woodpecker/pr/build-package
|
||||||
|
- ci/woodpecker/pr/build-container
|
||||||
|
- ci/woodpecker/pr/docs
|
||||||
|
enforce_admins: false
|
||||||
|
required_linear_history: true
|
||||||
|
restrictions: null
|
||||||
|
- name: docs
|
||||||
|
protection:
|
||||||
|
required_pull_request_reviews: null
|
||||||
|
required_status_checks: null
|
||||||
|
enforce_admins: true
|
||||||
|
required_linear_history: true
|
||||||
|
restrictions:
|
||||||
|
apps: []
|
||||||
|
users: []
|
||||||
|
teams:
|
||||||
|
- bot
|
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/dist
|
||||||
|
/release
|
||||||
|
/wp-git-clone*
|
||||||
|
docs/data/data-raw.yaml
|
||||||
|
|
||||||
|
coverage.out
|
||||||
|
CHANGELOG.md
|
47
.gitsv/config.yml
Normal file
47
.gitsv/config.yml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
version: "1.1"
|
||||||
|
|
||||||
|
versioning:
|
||||||
|
update-major: []
|
||||||
|
update-minor: [feat]
|
||||||
|
update-patch: [fix, perf, refactor, chore, test, ci, docs]
|
||||||
|
|
||||||
|
tag:
|
||||||
|
pattern: "v%d.%d.%d"
|
||||||
|
|
||||||
|
release-notes:
|
||||||
|
sections:
|
||||||
|
- name: Features
|
||||||
|
commit-types: [feat]
|
||||||
|
section-type: commits
|
||||||
|
- name: Bug Fixes
|
||||||
|
commit-types: [fix]
|
||||||
|
section-type: commits
|
||||||
|
- name: Performance Improvements
|
||||||
|
commit-types: [perf]
|
||||||
|
section-type: commits
|
||||||
|
- name: Code Refactoring
|
||||||
|
commit-types: [refactor]
|
||||||
|
section-type: commits
|
||||||
|
- name: Others
|
||||||
|
commit-types: [chore]
|
||||||
|
section-type: commits
|
||||||
|
- name: Testing
|
||||||
|
commit-types: [test]
|
||||||
|
section-type: commits
|
||||||
|
- name: CI Pipeline
|
||||||
|
commit-types: [ci]
|
||||||
|
section-type: commits
|
||||||
|
- name: Documentation
|
||||||
|
commit-types: [docs]
|
||||||
|
section-type: commits
|
||||||
|
- name: BREAKING CHANGES
|
||||||
|
section-type: breaking-changes
|
||||||
|
|
||||||
|
commit-message:
|
||||||
|
footer:
|
||||||
|
issue:
|
||||||
|
key: issue
|
||||||
|
add-value-prefix: "#"
|
||||||
|
issue:
|
||||||
|
regex: "#?[0-9]+"
|
104
.golangci.yml
Normal file
104
.golangci.yml
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
linters:
|
||||||
|
enable-all: false
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- errcheck
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- staticcheck
|
||||||
|
- typecheck
|
||||||
|
- unused
|
||||||
|
- asasalint
|
||||||
|
- asciicheck
|
||||||
|
- bidichk
|
||||||
|
- bodyclose
|
||||||
|
- containedctx
|
||||||
|
- contextcheck
|
||||||
|
- decorder
|
||||||
|
- dogsled
|
||||||
|
- dupl
|
||||||
|
- dupword
|
||||||
|
- durationcheck
|
||||||
|
- errchkjson
|
||||||
|
- errname
|
||||||
|
- errorlint
|
||||||
|
- execinquery
|
||||||
|
- exhaustive
|
||||||
|
- exportloopref
|
||||||
|
- forcetypeassert
|
||||||
|
- ginkgolinter
|
||||||
|
- gocheckcompilerdirectives
|
||||||
|
- gochecknoglobals
|
||||||
|
- gochecknoinits
|
||||||
|
- gocognit
|
||||||
|
- goconst
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
- godot
|
||||||
|
- godox
|
||||||
|
- goerr113
|
||||||
|
- gofmt
|
||||||
|
- gofumpt
|
||||||
|
- goheader
|
||||||
|
- goimports
|
||||||
|
- gomnd
|
||||||
|
- gomoddirectives
|
||||||
|
- gomodguard
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- grouper
|
||||||
|
- importas
|
||||||
|
- interfacebloat
|
||||||
|
- ireturn
|
||||||
|
- lll
|
||||||
|
- loggercheck
|
||||||
|
- maintidx
|
||||||
|
- makezero
|
||||||
|
- misspell
|
||||||
|
- musttag
|
||||||
|
- nakedret
|
||||||
|
- nestif
|
||||||
|
- nilerr
|
||||||
|
- nilnil
|
||||||
|
- nlreturn
|
||||||
|
- noctx
|
||||||
|
- nolintlint
|
||||||
|
- nonamedreturns
|
||||||
|
- nosprintfhostport
|
||||||
|
- prealloc
|
||||||
|
- predeclared
|
||||||
|
- promlinter
|
||||||
|
- reassign
|
||||||
|
- revive
|
||||||
|
# - rowserrcheck
|
||||||
|
# - sqlclosecheck
|
||||||
|
# - structcheck
|
||||||
|
- stylecheck
|
||||||
|
- tagliatelle
|
||||||
|
- tenv
|
||||||
|
- testableexamples
|
||||||
|
- thelper
|
||||||
|
- tparallel
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- usestdlibvars
|
||||||
|
# - wastedassign
|
||||||
|
- whitespace
|
||||||
|
- wsl
|
||||||
|
- zerologlint
|
||||||
|
fast: false
|
||||||
|
|
||||||
|
run:
|
||||||
|
timeout: 3m
|
||||||
|
|
||||||
|
linters-settings:
|
||||||
|
gofumpt:
|
||||||
|
extra-rules: true
|
||||||
|
ireturn:
|
||||||
|
allow:
|
||||||
|
- anon
|
||||||
|
- error
|
||||||
|
- empty
|
||||||
|
- stdlib
|
||||||
|
- ^github\.com\/cenkalti\/backoff\/\S+\.BackOff$
|
1
.lycheeignore
Normal file
1
.lycheeignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://hub.docker.com/r/thegeeklab/*
|
6
.markdownlint.yml
Normal file
6
.markdownlint.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
default: True
|
||||||
|
MD013: False
|
||||||
|
MD041: False
|
||||||
|
MD004:
|
||||||
|
style: dash
|
2
.prettierignore
Normal file
2
.prettierignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.tpl.md
|
||||||
|
LICENSE
|
66
.woodpecker/build-container.yml
Normal file
66
.woodpecker/build-container.yml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
when:
|
||||||
|
- event: [pull_request, tag]
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: dryrun
|
||||||
|
image: quay.io/thegeeklab/wp-docker-buildx:2
|
||||||
|
settings:
|
||||||
|
containerfile: Containerfile.multiarch
|
||||||
|
dry_run: true
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
|
provenance: false
|
||||||
|
repo: ${CI_REPO}
|
||||||
|
when:
|
||||||
|
- event: [pull_request]
|
||||||
|
|
||||||
|
publish-dockerhub:
|
||||||
|
group: container
|
||||||
|
image: quay.io/thegeeklab/wp-docker-buildx:2
|
||||||
|
settings:
|
||||||
|
auto_tag: true
|
||||||
|
containerfile: Containerfile.multiarch
|
||||||
|
password:
|
||||||
|
from_secret: docker_password
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
|
provenance: false
|
||||||
|
repo: ${CI_REPO}
|
||||||
|
username:
|
||||||
|
from_secret: docker_username
|
||||||
|
when:
|
||||||
|
- event: [tag]
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
|
||||||
|
publish-quay:
|
||||||
|
group: container
|
||||||
|
image: quay.io/thegeeklab/wp-docker-buildx:2
|
||||||
|
settings:
|
||||||
|
auto_tag: true
|
||||||
|
containerfile: Containerfile.multiarch
|
||||||
|
password:
|
||||||
|
from_secret: quay_password
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
|
provenance: false
|
||||||
|
registry: quay.io
|
||||||
|
repo: quay.io/${CI_REPO}
|
||||||
|
username:
|
||||||
|
from_secret: quay_username
|
||||||
|
when:
|
||||||
|
- event: [tag]
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- test
|
41
.woodpecker/build-package.yml
Normal file
41
.woodpecker/build-package.yml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
when:
|
||||||
|
- event: [pull_request, tag]
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: docker.io/techknowlogick/xgo:go-1.21.x
|
||||||
|
commands:
|
||||||
|
- ln -s $(pwd) /source
|
||||||
|
- make release
|
||||||
|
|
||||||
|
- name: executable
|
||||||
|
image: quay.io/thegeeklab/alpine-tools
|
||||||
|
commands:
|
||||||
|
- $(find dist/ -executable -type f -iname ${CI_REPO_NAME}-linux-amd64) --help
|
||||||
|
|
||||||
|
- name: changelog
|
||||||
|
image: quay.io/thegeeklab/git-sv
|
||||||
|
commands:
|
||||||
|
- git sv current-version
|
||||||
|
- git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md
|
||||||
|
- cat CHANGELOG.md
|
||||||
|
|
||||||
|
- name: publish-github
|
||||||
|
image: docker.io/plugins/github-release
|
||||||
|
settings:
|
||||||
|
api_key:
|
||||||
|
from_secret: github_token
|
||||||
|
files:
|
||||||
|
- dist/*
|
||||||
|
note: CHANGELOG.md
|
||||||
|
overwrite: true
|
||||||
|
title: ${CI_COMMIT_TAG}
|
||||||
|
when:
|
||||||
|
- event: [tag]
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- test
|
79
.woodpecker/docs.yml
Normal file
79
.woodpecker/docs.yml
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
when:
|
||||||
|
- event: [pull_request, tag]
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: markdownlint
|
||||||
|
image: quay.io/thegeeklab/markdownlint-cli
|
||||||
|
group: test
|
||||||
|
commands:
|
||||||
|
- markdownlint 'README.md' 'CONTRIBUTING.md'
|
||||||
|
|
||||||
|
- name: spellcheck
|
||||||
|
image: quay.io/thegeeklab/alpine-tools
|
||||||
|
group: test
|
||||||
|
commands:
|
||||||
|
- spellchecker --files '_docs/**/*.md' 'README.md' 'CONTRIBUTING.md' -d .dictionary -p spell indefinite-article syntax-urls
|
||||||
|
environment:
|
||||||
|
FORCE_COLOR: "true"
|
||||||
|
|
||||||
|
- name: link-validation
|
||||||
|
image: docker.io/lycheeverse/lychee
|
||||||
|
group: test
|
||||||
|
commands:
|
||||||
|
- lychee --no-progress --format detailed _docs/content README.md
|
||||||
|
|
||||||
|
- name: publish
|
||||||
|
image: quay.io/thegeeklab/wp-git-action
|
||||||
|
settings:
|
||||||
|
action:
|
||||||
|
- pages
|
||||||
|
author_email: bot@thegeeklab.de
|
||||||
|
author_name: thegeeklab-bot
|
||||||
|
branch: docs
|
||||||
|
message: "[skip ci] auto-update documentation"
|
||||||
|
netrc_password:
|
||||||
|
from_secret: github_token
|
||||||
|
pages_directory: _docs/
|
||||||
|
when:
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
|
||||||
|
- name: pushrm-dockerhub
|
||||||
|
image: docker.io/chko/docker-pushrm:1
|
||||||
|
secrets:
|
||||||
|
- source: docker_password
|
||||||
|
target: DOCKER_PASS
|
||||||
|
- source: docker_username
|
||||||
|
target: DOCKER_USER
|
||||||
|
environment:
|
||||||
|
PUSHRM_FILE: README.md
|
||||||
|
PUSHRM_SHORT: Woodpecker CI plugin to clone git repositories
|
||||||
|
PUSHRM_TARGET: ${CI_REPO}
|
||||||
|
when:
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
status: [success]
|
||||||
|
|
||||||
|
- name: pushrm-quay
|
||||||
|
image: docker.io/chko/docker-pushrm:1
|
||||||
|
secrets:
|
||||||
|
- source: quay_token
|
||||||
|
target: APIKEY__QUAY_IO
|
||||||
|
environment:
|
||||||
|
PUSHRM_FILE: README.md
|
||||||
|
PUSHRM_TARGET: quay.io/${CI_REPO}
|
||||||
|
when:
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
status: [success]
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- build-package
|
||||||
|
- build-container
|
26
.woodpecker/notify.yml
Normal file
26
.woodpecker/notify.yml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
when:
|
||||||
|
- event: [tag]
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
|
||||||
|
runs_on: [success, failure]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: matrix
|
||||||
|
image: quay.io/thegeeklab/wp-matrix
|
||||||
|
settings:
|
||||||
|
homeserver:
|
||||||
|
from_secret: matrix_homeserver
|
||||||
|
password:
|
||||||
|
from_secret: matrix_password
|
||||||
|
roomid:
|
||||||
|
from_secret: matrix_roomid
|
||||||
|
username:
|
||||||
|
from_secret: matrix_username
|
||||||
|
when:
|
||||||
|
- status: [success, failure]
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- docs
|
17
.woodpecker/test.yml
Normal file
17
.woodpecker/test.yml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
when:
|
||||||
|
- event: [pull_request, tag]
|
||||||
|
- event: [push, manual]
|
||||||
|
branch:
|
||||||
|
- ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: lint
|
||||||
|
image: docker.io/library/golang:1.21
|
||||||
|
commands:
|
||||||
|
- make lint
|
||||||
|
|
||||||
|
- name: test
|
||||||
|
image: docker.io/library/golang:1.21
|
||||||
|
commands:
|
||||||
|
- make test
|
31
CONTRIBUTING.md
Normal file
31
CONTRIBUTING.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
If you think you have found a **security issue**, please do not mention it in this repository.
|
||||||
|
Instead, send an email to `security@thegeeklab.de` with as many details as possible so it can be handled confidential.
|
||||||
|
|
||||||
|
## Bug Reports and Feature Requests
|
||||||
|
|
||||||
|
If you have found a **bug** or have a **feature request** please use the search first in case a similar issue already exists.
|
||||||
|
If not, please create an issue in this repository
|
||||||
|
|
||||||
|
## Code
|
||||||
|
|
||||||
|
If you would like to fix a bug or implement a feature, please fork the repository and create a Pull Request.
|
||||||
|
|
||||||
|
Before you start any Pull Request, it is recommended that you create an issue to discuss first if you have any
|
||||||
|
doubts about requirement or implementation. That way you can be sure that the maintainer(s) agree on what to change and how,
|
||||||
|
and you can hopefully get a quick merge afterwards.
|
||||||
|
|
||||||
|
Pull Requests can only be merged once all status checks are green.
|
||||||
|
|
||||||
|
## Do not force push to your Pull Request branch
|
||||||
|
|
||||||
|
Please do not force push to your Pull Requests branch after you have created your Pull Request, as doing so makes it harder for us to review your work.
|
||||||
|
Pull Requests will always be squashed by us when we merge your work. Commit as many times as you need in your Pull Request branch.
|
||||||
|
|
||||||
|
## Re-requesting a review
|
||||||
|
|
||||||
|
Please do not ping your reviewer(s) by mentioning them in a new comment. Instead, use the re-request review functionality.
|
||||||
|
Read more about this in the [GitHub docs, Re-requesting a review](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request#re-requesting-a-review).
|
25
Containerfile.multiarch
Normal file
25
Containerfile.multiarch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
FROM --platform=$BUILDPLATFORM golang:1.21@sha256:672a2286da3ee7a854c3e0a56e0838918d0dbb1c18652992930293312de898a6 as build
|
||||||
|
|
||||||
|
ARG TARGETOS
|
||||||
|
ARG TARGETARCH
|
||||||
|
|
||||||
|
ADD . /src
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
RUN make build
|
||||||
|
|
||||||
|
FROM alpine:3.19@sha256:51b67269f354137895d43f3b3d810bfacd3945438e94dc5ac55fdac340352f48
|
||||||
|
|
||||||
|
LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>"
|
||||||
|
LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>"
|
||||||
|
LABEL org.opencontainers.image.title="wp-git-clone"
|
||||||
|
LABEL org.opencontainers.image.url="https://github.com/thegeeklab/wp-git-clone"
|
||||||
|
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/wp-git-clone"
|
||||||
|
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/wp-git-clone"
|
||||||
|
|
||||||
|
RUN apk --update add --no-cache git openssh curl git-lfs && \
|
||||||
|
rm -rf /var/cache/apk/* && \
|
||||||
|
rm -rf /tmp/*
|
||||||
|
|
||||||
|
COPY --from=build /src/dist/wp-git-clone /bin/wp-git-clone
|
||||||
|
ENTRYPOINT [ "/bin/wp-git-clone" ]
|
202
LICENSE
Normal file
202
LICENSE
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright 2022 Robert Kaussow <mail@thegeeklab.de>
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
107
Makefile
Normal file
107
Makefile
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
# renovate: datasource=github-releases depName=mvdan/gofumpt
|
||||||
|
GOFUMPT_PACKAGE_VERSION := v0.5.0
|
||||||
|
# renovate: datasource=github-releases depName=golangci/golangci-lint
|
||||||
|
GOLANGCI_LINT_PACKAGE_VERSION := v1.55.2
|
||||||
|
|
||||||
|
EXECUTABLE := wp-git-clone
|
||||||
|
|
||||||
|
DIST := dist
|
||||||
|
DIST_DIRS := $(DIST)
|
||||||
|
IMPORT := github.com/thegeeklab/$(EXECUTABLE)
|
||||||
|
|
||||||
|
GO ?= go
|
||||||
|
CWD ?= $(shell pwd)
|
||||||
|
PACKAGES ?= $(shell go list ./...)
|
||||||
|
SOURCES ?= $(shell find . -name "*.go" -type f)
|
||||||
|
|
||||||
|
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@$(GOFUMPT_PACKAGE_VERSION)
|
||||||
|
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_PACKAGE_VERSION)
|
||||||
|
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||||
|
GOTESTSUM_PACKAGE ?= gotest.tools/gotestsum@latest
|
||||||
|
|
||||||
|
GENERATE ?=
|
||||||
|
XGO_VERSION := go-1.21.x
|
||||||
|
XGO_TARGETS ?= linux/amd64,linux/arm-6,linux/arm-7,linux/arm64
|
||||||
|
|
||||||
|
TARGETOS ?= linux
|
||||||
|
TARGETARCH ?= amd64
|
||||||
|
ifneq ("$(TARGETVARIANT)","")
|
||||||
|
GOARM ?= $(subst v,,$(TARGETVARIANT))
|
||||||
|
endif
|
||||||
|
TAGS ?= netgo
|
||||||
|
|
||||||
|
ifndef VERSION
|
||||||
|
ifneq ($(CI_COMMIT_TAG),)
|
||||||
|
VERSION ?= $(subst v,,$(CI_COMMIT_TAG))
|
||||||
|
else
|
||||||
|
VERSION ?= $(shell git rev-parse --short HEAD)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef DATE
|
||||||
|
DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%S%z")
|
||||||
|
endif
|
||||||
|
|
||||||
|
LDFLAGS += -s -w -X "main.BuildVersion=$(VERSION)" -X "main.BuildDate=$(DATE)"
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: clean build
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
$(GO) clean -i ./...
|
||||||
|
rm -rf $(DIST_DIRS)
|
||||||
|
|
||||||
|
.PHONY: fmt
|
||||||
|
fmt:
|
||||||
|
$(GO) run $(GOFUMPT_PACKAGE) -extra -w $(SOURCES)
|
||||||
|
|
||||||
|
.PHONY: golangci-lint
|
||||||
|
golangci-lint:
|
||||||
|
$(GO) run $(GOLANGCI_LINT_PACKAGE) run
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint: golangci-lint
|
||||||
|
|
||||||
|
.PHONY: generate
|
||||||
|
generate:
|
||||||
|
$(GO) generate $(GENERATE)
|
||||||
|
|
||||||
|
.PHONY: generate-docs
|
||||||
|
generate-docs:
|
||||||
|
$(GO) generate ./cmd/$(EXECUTABLE)/flags.go
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test:
|
||||||
|
$(GO) run $(GOTESTSUM_PACKAGE) --no-color=false -- -coverprofile=coverage.out $(PACKAGES)
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build: $(DIST)/$(EXECUTABLE)
|
||||||
|
|
||||||
|
$(DIST)/$(EXECUTABLE): $(SOURCES)
|
||||||
|
GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) GOARM=$(GOARM) $(GO) build -v -tags '$(TAGS)' -ldflags '-extldflags "-static" $(LDFLAGS)' -o $@ ./cmd/$(EXECUTABLE)
|
||||||
|
|
||||||
|
$(DIST_DIRS):
|
||||||
|
mkdir -p $(DIST_DIRS)
|
||||||
|
|
||||||
|
.PHONY: xgo
|
||||||
|
xgo: | $(DIST_DIRS)
|
||||||
|
$(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -v -ldflags '-extldflags "-static" $(LDFLAGS)' -tags '$(TAGS)' -targets '$(XGO_TARGETS)' -out $(EXECUTABLE) --pkg cmd/$(EXECUTABLE) .
|
||||||
|
cp /build/* $(CWD)/$(DIST)
|
||||||
|
ls -l $(CWD)/$(DIST)
|
||||||
|
|
||||||
|
.PHONY: checksum
|
||||||
|
checksum:
|
||||||
|
cd $(DIST); $(foreach file,$(wildcard $(DIST)/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;)
|
||||||
|
ls -l $(CWD)/$(DIST)
|
||||||
|
|
||||||
|
.PHONY: release
|
||||||
|
release: xgo checksum
|
||||||
|
|
||||||
|
.PHONY: deps
|
||||||
|
deps:
|
||||||
|
$(GO) mod download
|
||||||
|
$(GO) install $(GOFUMPT_PACKAGE)
|
||||||
|
$(GO) install $(GOLANGCI_LINT_PACKAGE)
|
||||||
|
$(GO) install $(XGO_PACKAGE)
|
||||||
|
$(GO) install $(GOTESTSUM_PACKAGE)
|
21
README.md
Normal file
21
README.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# wp-git-clone
|
||||||
|
|
||||||
|
Woodpecker CI plugin to clone git repositories
|
||||||
|
|
||||||
|
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/wp-git-clone/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/wp-git-clone)
|
||||||
|
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/wp-git-clone)
|
||||||
|
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/wp-git-clone)
|
||||||
|
[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/wp-git-clone)](https://goreportcard.com/report/github.com/thegeeklab/wp-git-clone)
|
||||||
|
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/wp-git-clone)](https://github.com/thegeeklab/wp-git-clone/graphs/contributors)
|
||||||
|
[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/wp-git-clone)
|
||||||
|
[![License: Apache-2.0](https://img.shields.io/github/license/thegeeklab/wp-git-clone)](https://github.com/thegeeklab/wp-git-clone/blob/main/LICENSE)
|
||||||
|
|
||||||
|
Woodpecker CI plugin to clone git repositories. You can find the full documentation at [https://woodpecker-plugins.geekdocs.de](https://woodpecker-plugins.geekdocs.de/plugins/wp-git-clone).
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
Special thanks to all [contributors](https://github.com/thegeeklab/wp-git-clone/graphs/contributors). If you would like to contribute, please see the [instructions](https://github.com/thegeeklab/wp-git-clone/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the Apache-2.0 License - see the [LICENSE](https://github.com/thegeeklab/wp-git-clone/blob/main/LICENSE) file for details.
|
57
cmd/wp-git-clone/docs.go
Normal file
57
cmd/wp-git-clone/docs.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//go:build generate
|
||||||
|
// +build generate
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"embed"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/thegeeklab/wp-git-clone/plugin"
|
||||||
|
"github.com/thegeeklab/wp-plugin-go/docs"
|
||||||
|
wp "github.com/thegeeklab/wp-plugin-go/plugin"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed templates/docs-data.yaml.tmpl
|
||||||
|
var yamlTemplate embed.FS
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
settings := &plugin.Settings{}
|
||||||
|
app := &cli.App{
|
||||||
|
Flags: settingsFlags(settings, wp.FlagsPluginCategory),
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := toYAML(app)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fi, err := os.Create("../../docs/data/data-raw.yaml")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer fi.Close()
|
||||||
|
if _, err := fi.WriteString(out); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toYAML(app *cli.App) (string, error) {
|
||||||
|
var w bytes.Buffer
|
||||||
|
|
||||||
|
yamlTmpl, err := template.New("docs").ParseFS(yamlTemplate, "templates/docs-data.yaml.tmpl")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(yamlTmpl)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := yamlTmpl.ExecuteTemplate(&w, "docs-data.yaml.tmpl", docs.GetTemplateData(app)); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return w.String(), nil
|
||||||
|
}
|
183
cmd/wp-git-clone/flags.go
Normal file
183
cmd/wp-git-clone/flags.go
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
// Copyright (c) 2020, the Drone Plugins project authors.
|
||||||
|
// Copyright (c) 2021, Robert Kaussow <mail@thegeeklab.de>
|
||||||
|
|
||||||
|
// Use of this source code is governed by an Apache 2.0 license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/thegeeklab/wp-git-clone/plugin"
|
||||||
|
"github.com/thegeeklab/wp-plugin-go/types"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// settingsFlags has the cli.Flags for the plugin.Settings.
|
||||||
|
//
|
||||||
|
//go:generate go run docs.go flags.go
|
||||||
|
func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
||||||
|
return []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "remote",
|
||||||
|
Usage: "git remote url",
|
||||||
|
EnvVars: []string{"PLUGIN_REMOTE", "CI_REPO_CLONE_URL"},
|
||||||
|
Destination: &settings.Repo.RemoteURL,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "remote-ssh",
|
||||||
|
Usage: "git clone ssh url",
|
||||||
|
EnvVars: []string{"PLUGIN_REMOTE_SSH", "CI_REPO_CLONE_SSH_URL"},
|
||||||
|
Destination: &settings.Repo.RemoteURL,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "workdir",
|
||||||
|
Usage: "path to clone git repository",
|
||||||
|
EnvVars: []string{"PLUGIN_WORKDIR", "CI_WORKSPACE"},
|
||||||
|
Destination: &settings.WorkDir,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "sha",
|
||||||
|
Usage: "git commit sha",
|
||||||
|
EnvVars: []string{"PLUGIN_COMMIT_SHA", "CI_COMMIT_SHA"},
|
||||||
|
Destination: &settings.Repo.CommitSha,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "ref",
|
||||||
|
Value: "refs/heads/main",
|
||||||
|
Usage: "git commit ref",
|
||||||
|
EnvVars: []string{"PLUGIN_COMMIT_REF", "CI_COMMIT_REF"},
|
||||||
|
Destination: &settings.Repo.CommitRef,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "event",
|
||||||
|
Value: "push",
|
||||||
|
Usage: "pipeline event",
|
||||||
|
EnvVars: []string{"CI_PIPELINE_EVENT"},
|
||||||
|
Destination: &settings.Pipeline.Event,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "netrc.machine",
|
||||||
|
Usage: "netrc machine",
|
||||||
|
EnvVars: []string{"CI_NETRC_MACHINE"},
|
||||||
|
Destination: &settings.Netrc.Machine,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "netrc.username",
|
||||||
|
Usage: "netrc username",
|
||||||
|
EnvVars: []string{"CI_NETRC_USERNAME"},
|
||||||
|
Destination: &settings.Netrc.Password,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "netrc.password",
|
||||||
|
Usage: "netrc password",
|
||||||
|
EnvVars: []string{"CI_NETRC_PASSWORD"},
|
||||||
|
Destination: &settings.Netrc.Password,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "depth",
|
||||||
|
Usage: "clone depth",
|
||||||
|
EnvVars: []string{"PLUGIN_DEPTH"},
|
||||||
|
Destination: &settings.Depth,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "recursive",
|
||||||
|
Usage: "clone submodules",
|
||||||
|
EnvVars: []string{"PLUGIN_RECURSIVE"},
|
||||||
|
Value: true,
|
||||||
|
Destination: &settings.Recursive,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "tags",
|
||||||
|
Usage: "clone tags, if not explicitly set and event is tag its default is true else false",
|
||||||
|
EnvVars: []string{"PLUGIN_TAGS"},
|
||||||
|
Destination: &settings.Tags,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "insecure-ssl-verify",
|
||||||
|
Usage: "set SSL verification of the remote machine",
|
||||||
|
EnvVars: []string{"PLUGIN_INSECURE_SSL_VERIFY"},
|
||||||
|
Destination: &settings.Repo.InsecureSSLVerify,
|
||||||
|
Value: false,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "submodule-update-remote",
|
||||||
|
Usage: "update remote submodules",
|
||||||
|
EnvVars: []string{"PLUGIN_SUBMODULES_UPDATE_REMOTE", "PLUGIN_SUBMODULE_UPDATE_REMOTE"},
|
||||||
|
Destination: &settings.Repo.SubmoduleRemote,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.GenericFlag{
|
||||||
|
Name: "submodule-override",
|
||||||
|
Usage: "json map of submodule overrides",
|
||||||
|
EnvVars: []string{"PLUGIN_SUBMODULE_OVERRIDE"},
|
||||||
|
Value: &types.MapFlag{},
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "submodule-partial",
|
||||||
|
Usage: "update submodules via partial clone",
|
||||||
|
EnvVars: []string{"PLUGIN_SUBMODULES_PARTIAL", "PLUGIN_SUBMODULE_PARTIAL"},
|
||||||
|
Value: true,
|
||||||
|
Destination: &settings.Repo.SubmodulePartial,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "lfs",
|
||||||
|
Usage: "whether to retrieve LFS content if available",
|
||||||
|
EnvVars: []string{"PLUGIN_LFS"},
|
||||||
|
Value: true,
|
||||||
|
Destination: &settings.Lfs,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "branch",
|
||||||
|
Usage: "change branch name",
|
||||||
|
EnvVars: []string{"PLUGIN_BRANCH", "CI_COMMIT_BRANCH", "CI_REPO_DEFAULT_BRANCH"},
|
||||||
|
Destination: &settings.Repo.Branch,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "partial",
|
||||||
|
Usage: "enable/disable partial clone",
|
||||||
|
EnvVars: []string{"PLUGIN_PARTIAL"},
|
||||||
|
Value: false,
|
||||||
|
Destination: &settings.Partial,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "safe-directory",
|
||||||
|
Usage: "define/replace safe directories",
|
||||||
|
EnvVars: []string{"PLUGIN_SAFE_DIRECTORY", "CI_WORKSPACE"},
|
||||||
|
Destination: &settings.Repo.SafeDirectory,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "use-ssh",
|
||||||
|
Usage: "using ssh for git clone",
|
||||||
|
EnvVars: []string{"PLUGIN_USE_SSH"},
|
||||||
|
Value: false,
|
||||||
|
Destination: &settings.UseSSH,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "ssh-key",
|
||||||
|
Usage: "ssh key for ssh clone",
|
||||||
|
EnvVars: []string{"PLUGIN_SSH_KEY"},
|
||||||
|
Destination: &settings.SSHKey,
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
34
cmd/wp-git-clone/main.go
Normal file
34
cmd/wp-git-clone/main.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (c) 2020, the Drone Plugins project authors.
|
||||||
|
// Copyright (c) 2021, Robert Kaussow <mail@thegeeklab.de>
|
||||||
|
|
||||||
|
// Use of this source code is governed by an Apache 2.0 license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/thegeeklab/wp-git-clone/plugin"
|
||||||
|
|
||||||
|
wp "github.com/thegeeklab/wp-plugin-go/plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:gochecknoglobals
|
||||||
|
var (
|
||||||
|
BuildVersion = "devel"
|
||||||
|
BuildDate = "00000000"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
settings := &plugin.Settings{}
|
||||||
|
options := wp.Options{
|
||||||
|
Name: "wp-git-clone",
|
||||||
|
Description: "Clone git repository",
|
||||||
|
Version: BuildVersion,
|
||||||
|
VersionMetadata: fmt.Sprintf("date=%s", BuildDate),
|
||||||
|
Flags: settingsFlags(settings, wp.FlagsPluginCategory),
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.New(options, settings).Run()
|
||||||
|
}
|
14
cmd/wp-git-clone/templates/docs-data.yaml.tmpl
Normal file
14
cmd/wp-git-clone/templates/docs-data.yaml.tmpl
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
{{- if .GlobalArgs }}
|
||||||
|
properties:
|
||||||
|
{{- range $v := .GlobalArgs }}
|
||||||
|
- name: {{ $v.Name }}
|
||||||
|
{{- with $v.Description }}
|
||||||
|
description: |
|
||||||
|
{{ . }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with $v.Default }}
|
||||||
|
defaultvalue: {{ . }}
|
||||||
|
{{- end }}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
66
docs/content/_index.md
Normal file
66
docs/content/_index.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
title: wp-git-clone
|
||||||
|
---
|
||||||
|
|
||||||
|
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/wp-git-clone/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/wp-git-clone)
|
||||||
|
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/wp-git-clone)
|
||||||
|
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/wp-git-clone)
|
||||||
|
[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/wp-git-clone)](https://goreportcard.com/report/github.com/thegeeklab/wp-git-clone)
|
||||||
|
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/wp-git-clone)](https://github.com/thegeeklab/wp-git-clone/graphs/contributors)
|
||||||
|
[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/wp-git-clone)
|
||||||
|
[![License: Apache-2.0](https://img.shields.io/github/license/thegeeklab/wp-git-clone)](https://github.com/thegeeklab/wp-git-clone/blob/main/LICENSE)
|
||||||
|
|
||||||
|
Woodpecker CI plugin to clone git repositories.
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- spellchecker-disable -->
|
||||||
|
{{< toc >}}
|
||||||
|
<!-- spellchecker-enable -->
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```YAML
|
||||||
|
clone:
|
||||||
|
git:
|
||||||
|
image: quay.io/thegeeklab/wp-git-clone
|
||||||
|
settings:
|
||||||
|
depth: 50
|
||||||
|
lfs: false
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- spellchecker-disable -->
|
||||||
|
{{< propertylist name=wp-git-clone.data sort=name >}}
|
||||||
|
<!-- spellchecker-enable -->
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Build the binary with the following command:
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
make build
|
||||||
|
```
|
||||||
|
|
||||||
|
Build the container image with the following command:
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
docker build --file Containerfile.multiarch --tag thegeeklab/wp-git-clone .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
docker run --rm \
|
||||||
|
-e CI_REPO_CLONE_URL=https://github.com/octocat/Hello-World.git \
|
||||||
|
-e CI_PIPELINE_EVENT=push \
|
||||||
|
-e CI_COMMIT_SHA=553c2077f0edc3d5dc5d17262f6aa498e69d6f8e \
|
||||||
|
-e CI_COMMIT_REF=refs/heads/master \
|
||||||
|
-e CI_WORKSPACE=/tmp/wp_git_testrepo \
|
||||||
|
-v $(pwd):/build:z \
|
||||||
|
-w /build \
|
||||||
|
quay.io/thegeeklab/wp-git-clone
|
||||||
|
```
|
100
docs/data/data.yaml
Normal file
100
docs/data/data.yaml
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
---
|
||||||
|
properties:
|
||||||
|
- name: branch
|
||||||
|
description: |
|
||||||
|
Change branch name.
|
||||||
|
|
||||||
|
- name: ci_netrc_machine
|
||||||
|
description: |
|
||||||
|
Netrc machine.
|
||||||
|
|
||||||
|
- name: ci_netrc_password
|
||||||
|
description: |
|
||||||
|
Netrc password.
|
||||||
|
|
||||||
|
- name: ci_netrc_username
|
||||||
|
description: |
|
||||||
|
Metrc username.
|
||||||
|
|
||||||
|
- name: ci_pipeline_event
|
||||||
|
description: |
|
||||||
|
Pipeline event.
|
||||||
|
defaultvalue: "push"
|
||||||
|
|
||||||
|
- name: commit_ref
|
||||||
|
description: |
|
||||||
|
Git commit ref.
|
||||||
|
defaultvalue: "refs/heads/main"
|
||||||
|
|
||||||
|
- name: commit_sha
|
||||||
|
description: |
|
||||||
|
Git commit sha.
|
||||||
|
|
||||||
|
- name: depth
|
||||||
|
description: |
|
||||||
|
Clone depth.
|
||||||
|
defaultvalue: 0
|
||||||
|
|
||||||
|
- name: insecure_ssl_verify
|
||||||
|
description: |
|
||||||
|
Set SSL verification of the remote machine.
|
||||||
|
defaultvalue: false
|
||||||
|
|
||||||
|
- name: lfs
|
||||||
|
description: |
|
||||||
|
Whether to retrieve LFS content if available.
|
||||||
|
defaultvalue: true
|
||||||
|
|
||||||
|
- name: partial
|
||||||
|
description: |
|
||||||
|
Enable/disable partial clone.
|
||||||
|
defaultvalue: false
|
||||||
|
|
||||||
|
- name: recursive
|
||||||
|
description: |
|
||||||
|
Clone submodules.
|
||||||
|
defaultvalue: true
|
||||||
|
|
||||||
|
- name: remote
|
||||||
|
description: |
|
||||||
|
Git remote HTTP clone url.
|
||||||
|
|
||||||
|
- name: remote_ssh
|
||||||
|
description: |
|
||||||
|
Git remote SSH clone url.
|
||||||
|
|
||||||
|
- name: safe_directory
|
||||||
|
description: |
|
||||||
|
Define/replace safe directories.
|
||||||
|
|
||||||
|
- name: ssh_key
|
||||||
|
description: |
|
||||||
|
SSH key for ssh clone.
|
||||||
|
|
||||||
|
- name: submodule_override
|
||||||
|
description: |
|
||||||
|
JSON map of submodule overrides.
|
||||||
|
|
||||||
|
- name: submodules_partial
|
||||||
|
description: |
|
||||||
|
Update submodules via partial clone (`depth=1`).
|
||||||
|
defaultvalue: true
|
||||||
|
|
||||||
|
- name: submodules_update_remote
|
||||||
|
description: |
|
||||||
|
Update remote submodules.
|
||||||
|
defaultvalue: false
|
||||||
|
|
||||||
|
- name: tags
|
||||||
|
description: |
|
||||||
|
Clone tags, if not explicitly set and event is tag its default is `true` else `false`.
|
||||||
|
defaultvalue: false
|
||||||
|
|
||||||
|
- name: use_ssh
|
||||||
|
description: |
|
||||||
|
Using ssh for git clone.
|
||||||
|
defaultvalue: false
|
||||||
|
|
||||||
|
- name: workdir
|
||||||
|
description: |
|
||||||
|
Path to clone git repository.
|
92
git/clone.go
Normal file
92
git/clone.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"golang.org/x/sys/execabs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FetchSource fetches the source from remote.
|
||||||
|
func FetchSource(ref string, tags bool, depth int, filter string) *execabs.Cmd {
|
||||||
|
tagsOption := "--no-tags"
|
||||||
|
|
||||||
|
if tags {
|
||||||
|
tagsOption = "--tags"
|
||||||
|
}
|
||||||
|
|
||||||
|
args := []string{
|
||||||
|
"fetch",
|
||||||
|
tagsOption,
|
||||||
|
}
|
||||||
|
|
||||||
|
if depth != 0 {
|
||||||
|
args = append(args, fmt.Sprintf("--depth=%d", depth))
|
||||||
|
}
|
||||||
|
|
||||||
|
if filter != "" {
|
||||||
|
args = append(args, "--filter="+filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, "origin")
|
||||||
|
args = append(args, fmt.Sprintf("+%s:", ref))
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchLFS fetches lfs.
|
||||||
|
func FetchLFS() *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"lfs",
|
||||||
|
"fetch",
|
||||||
|
}
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckoutHead handles head checkout.
|
||||||
|
func CheckoutHead() *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"checkout",
|
||||||
|
"-qf",
|
||||||
|
"FETCH_HEAD",
|
||||||
|
}
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckoutSha handles commit checkout.
|
||||||
|
func CheckoutSha(repo Repository) *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"reset",
|
||||||
|
"--hard",
|
||||||
|
"-q",
|
||||||
|
repo.CommitSha,
|
||||||
|
}
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckoutLFS handles commit checkout.
|
||||||
|
func CheckoutLFS() *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"lfs",
|
||||||
|
"checkout",
|
||||||
|
}
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
66
git/clone_test.go
Normal file
66
git/clone_test.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestFetch tests if the arguments to `git fetch` are constructed properly.
|
||||||
|
func TestFetch(t *testing.T) {
|
||||||
|
testdata := []struct {
|
||||||
|
ref string
|
||||||
|
tags bool
|
||||||
|
depth int
|
||||||
|
exp []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"refs/heads/master",
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
[]string{
|
||||||
|
"/usr/bin/git",
|
||||||
|
"fetch",
|
||||||
|
"--no-tags",
|
||||||
|
"origin",
|
||||||
|
"+refs/heads/master:",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"refs/heads/master",
|
||||||
|
false,
|
||||||
|
50,
|
||||||
|
[]string{
|
||||||
|
"/usr/bin/git",
|
||||||
|
"fetch",
|
||||||
|
"--no-tags",
|
||||||
|
"--depth=50",
|
||||||
|
"origin",
|
||||||
|
"+refs/heads/master:",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"refs/heads/master",
|
||||||
|
true,
|
||||||
|
100,
|
||||||
|
[]string{
|
||||||
|
"/usr/bin/git",
|
||||||
|
"fetch",
|
||||||
|
"--tags",
|
||||||
|
"--depth=100",
|
||||||
|
"origin",
|
||||||
|
"+refs/heads/master:",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, td := range testdata {
|
||||||
|
c := FetchSource(td.ref, td.tags, td.depth, "")
|
||||||
|
if len(c.Args) != len(td.exp) {
|
||||||
|
t.Errorf("Expected: %s, got %s", td.exp, c.Args)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range c.Args {
|
||||||
|
if c.Args[i] != td.exp[i] {
|
||||||
|
t.Errorf("Expected: %s, got %s", td.exp, c.Args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
70
git/config.go
Normal file
70
git/config.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"golang.org/x/sys/execabs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ConfigSSLVerify disables globally the git ssl verification.
|
||||||
|
func ConfigSSLVerify(repo Repository) *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"config",
|
||||||
|
"--local",
|
||||||
|
"http.sslVerify",
|
||||||
|
strconv.FormatBool(repo.InsecureSSLVerify),
|
||||||
|
}
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigSafeDirectory disables globally the git ssl verification.
|
||||||
|
func ConfigSafeDirectory(repo Repository) *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"config",
|
||||||
|
"--local",
|
||||||
|
"--replace-all",
|
||||||
|
"safe.directory",
|
||||||
|
repo.SafeDirectory,
|
||||||
|
}
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigRemapSubmodule returns a git command that, when executed configures git to
|
||||||
|
// remap submodule urls.
|
||||||
|
func ConfigRemapSubmodule(name, url string) *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"config",
|
||||||
|
"--local",
|
||||||
|
fmt.Sprintf("submodule.%s.url", name),
|
||||||
|
url,
|
||||||
|
}
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigSSHCommand sets custom SSH key.
|
||||||
|
func ConfigSSHCommand(sshKey string) *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"config",
|
||||||
|
"--local",
|
||||||
|
"core.sshCommand",
|
||||||
|
"ssh -i " + sshKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
27
git/init.go
Normal file
27
git/init.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/execabs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RemoteRemove drops the defined remote from a git repo.
|
||||||
|
func Init(repo Repository) *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"init",
|
||||||
|
}
|
||||||
|
|
||||||
|
if repo.Branch != "" {
|
||||||
|
args = []string{
|
||||||
|
"init",
|
||||||
|
"-b",
|
||||||
|
repo.Branch,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
20
git/remote.go
Normal file
20
git/remote.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/execabs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RemoteAdd adds an additional remote to a git repo.
|
||||||
|
func RemoteAdd(url string) *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"remote",
|
||||||
|
"add",
|
||||||
|
"origin",
|
||||||
|
url,
|
||||||
|
}
|
||||||
|
|
||||||
|
return execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
}
|
30
git/submodule.go
Normal file
30
git/submodule.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/execabs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SubmoduleUpdate recursively initializes and updates submodules.
|
||||||
|
func SubmoduleUpdate(repo Repository) *execabs.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"submodule",
|
||||||
|
"update",
|
||||||
|
"--init",
|
||||||
|
"--recursive",
|
||||||
|
}
|
||||||
|
|
||||||
|
if repo.SubmodulePartial {
|
||||||
|
args = append(args, "--depth=1", "--recommend-shallow")
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := execabs.Command(
|
||||||
|
gitBin,
|
||||||
|
args...,
|
||||||
|
)
|
||||||
|
|
||||||
|
if repo.SubmoduleRemote {
|
||||||
|
cmd.Args = append(cmd.Args, "--remote")
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
100
git/submodule_test.go
Normal file
100
git/submodule_test.go
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestUpdateSubmodules tests if the arguments to `git submodule update`
|
||||||
|
// are constructed properly.
|
||||||
|
func TestUpdateSubmodules(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
partial bool
|
||||||
|
exp []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
[]string{
|
||||||
|
"/usr/bin/git",
|
||||||
|
"submodule",
|
||||||
|
"update",
|
||||||
|
"--init",
|
||||||
|
"--recursive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
[]string{
|
||||||
|
"/usr/bin/git",
|
||||||
|
"submodule",
|
||||||
|
"update",
|
||||||
|
"--init",
|
||||||
|
"--recursive",
|
||||||
|
"--depth=1",
|
||||||
|
"--recommend-shallow",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
repo := Repository{
|
||||||
|
SubmoduleRemote: false,
|
||||||
|
SubmodulePartial: tt.partial,
|
||||||
|
}
|
||||||
|
|
||||||
|
c := SubmoduleUpdate(repo)
|
||||||
|
if len(c.Args) != len(tt.exp) {
|
||||||
|
t.Errorf("Expected: %s, got %s", tt.exp, c.Args)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range c.Args {
|
||||||
|
if c.Args[i] != tt.exp[i] {
|
||||||
|
t.Errorf("Expected: %s, got %s", tt.exp, c.Args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestUpdateSubmodules tests if the arguments to `git submodule update`
|
||||||
|
// are constructed properly.
|
||||||
|
func TestUpdateSubmodulesRemote(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
exp []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
[]string{
|
||||||
|
"/usr/bin/git",
|
||||||
|
"submodule",
|
||||||
|
"update",
|
||||||
|
"--init",
|
||||||
|
"--recursive",
|
||||||
|
"--remote",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{
|
||||||
|
"/usr/bin/git",
|
||||||
|
"submodule",
|
||||||
|
"update",
|
||||||
|
"--init",
|
||||||
|
"--recursive",
|
||||||
|
"--remote",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
repo := Repository{
|
||||||
|
SubmoduleRemote: true,
|
||||||
|
SubmodulePartial: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
c := SubmoduleUpdate(repo)
|
||||||
|
if len(c.Args) != len(tt.exp) {
|
||||||
|
t.Errorf("Expected: %s, got %s", tt.exp, c.Args)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range c.Args {
|
||||||
|
if c.Args[i] != tt.exp[i] {
|
||||||
|
t.Errorf("Expected: %s, got %s", tt.exp, c.Args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
git/type.go
Normal file
18
git/type.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
const gitBin = "/usr/bin/git"
|
||||||
|
|
||||||
|
type Repository struct {
|
||||||
|
RemoteURL string
|
||||||
|
RemoteSSH string
|
||||||
|
Branch string
|
||||||
|
CommitSha string
|
||||||
|
CommitRef string
|
||||||
|
Submodules map[string]string
|
||||||
|
SubmoduleRemote bool
|
||||||
|
SubmodulePartial bool
|
||||||
|
|
||||||
|
InsecureSSLVerify bool
|
||||||
|
SafeDirectory string
|
||||||
|
InitExists bool
|
||||||
|
}
|
47
git/utils.go
Normal file
47
git/utils.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
netrcFile = `
|
||||||
|
machine %s
|
||||||
|
login %s
|
||||||
|
password %s
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
strictFilePerm = 0o600
|
||||||
|
)
|
||||||
|
|
||||||
|
// WriteNetrc writes the netrc file.
|
||||||
|
func WriteNetrc(machine, login, password string) error {
|
||||||
|
netrcContent := fmt.Sprintf(
|
||||||
|
netrcFile,
|
||||||
|
machine,
|
||||||
|
login,
|
||||||
|
password,
|
||||||
|
)
|
||||||
|
|
||||||
|
home := "/root"
|
||||||
|
|
||||||
|
if currentUser, err := user.Current(); err == nil {
|
||||||
|
home = currentUser.HomeDir
|
||||||
|
}
|
||||||
|
|
||||||
|
netpath := filepath.Join(
|
||||||
|
home,
|
||||||
|
".netrc",
|
||||||
|
)
|
||||||
|
|
||||||
|
return os.WriteFile(
|
||||||
|
netpath,
|
||||||
|
[]byte(netrcContent),
|
||||||
|
strictFilePerm,
|
||||||
|
)
|
||||||
|
}
|
32
go.mod
Normal file
32
go.mod
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
module github.com/thegeeklab/wp-git-clone
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/cenkalti/backoff/v4 v4.2.1
|
||||||
|
github.com/rs/zerolog v1.31.0
|
||||||
|
github.com/thegeeklab/wp-plugin-go v1.3.0
|
||||||
|
github.com/urfave/cli/v2 v2.26.0
|
||||||
|
golang.org/x/sys v0.15.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
|
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||||
|
github.com/google/uuid v1.1.1 // indirect
|
||||||
|
github.com/huandu/xstrings v1.3.3 // indirect
|
||||||
|
github.com/imdario/mergo v0.3.11 // indirect
|
||||||
|
github.com/joho/godotenv v1.5.1 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
|
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.0 // indirect
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
|
github.com/shopspring/decimal v1.2.0 // indirect
|
||||||
|
github.com/spf13/cast v1.3.1 // indirect
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||||
|
golang.org/x/crypto v0.17.0 // indirect
|
||||||
|
golang.org/x/net v0.19.0 // indirect
|
||||||
|
)
|
99
go.sum
Normal file
99
go.sum
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||||
|
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||||
|
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||||
|
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||||
|
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
|
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||||
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
|
||||||
|
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
|
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||||
|
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
|
||||||
|
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
|
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||||
|
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||||
|
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
|
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||||
|
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/thegeeklab/wp-plugin-go v1.3.0 h1:Yhz0dTDwXcbeaoyoPOXNDf2RzSoUixHuE+ML27cYy2E=
|
||||||
|
github.com/thegeeklab/wp-plugin-go v1.3.0/go.mod h1:EUOH6XJ8G/bcd6gmM6a6vLeta+keyX9ul1Es0F0r2Lc=
|
||||||
|
github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI=
|
||||||
|
github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
|
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||||
|
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
|
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||||
|
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||||
|
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
207
plugin/impl.go
Normal file
207
plugin/impl.go
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
// Copyright (c) 2023, Robert Kaussow <mail@thegeeklab.de>
|
||||||
|
|
||||||
|
// Use of this source code is governed by an Apache 2.0 license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/cenkalti/backoff/v4"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/thegeeklab/wp-git-clone/git"
|
||||||
|
"github.com/thegeeklab/wp-plugin-go/types"
|
||||||
|
"golang.org/x/sys/execabs"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
daemonBackoffMaxRetries = 3
|
||||||
|
daemonBackoffInitialInterval = 2 * time.Second
|
||||||
|
daemonBackoffMultiplier = 3.5
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrGitCloneDestintionNotValid = errors.New("destination not valid")
|
||||||
|
ErrTypeAssertionFailed = errors.New("type assertion failed")
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:revive
|
||||||
|
func (p *Plugin) run(ctx context.Context) error {
|
||||||
|
if err := p.FlagsFromContext(); err != nil {
|
||||||
|
return fmt.Errorf("validation failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := p.Validate(); err != nil {
|
||||||
|
return fmt.Errorf("validation failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := p.Execute(); err != nil {
|
||||||
|
return fmt.Errorf("execution failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate handles the settings validation of the plugin.
|
||||||
|
func (p *Plugin) Validate() error {
|
||||||
|
if p.Settings.WorkDir == "" {
|
||||||
|
var err error
|
||||||
|
if p.Settings.WorkDir, err = os.Getwd(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Settings.Pipeline.Event == "tag" && !p.Settings.Tags {
|
||||||
|
// tags clone not explicit set but pipeline is triggered by a tag
|
||||||
|
// auto set tags cloning to true
|
||||||
|
p.Settings.Tags = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Settings.Tags && p.Settings.Partial {
|
||||||
|
log.Warn().Msg("ignore partial clone as tags are fetched")
|
||||||
|
|
||||||
|
// if tag fetching is enabled per event or setting, disable partial clone
|
||||||
|
p.Settings.Partial = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Settings.Partial {
|
||||||
|
p.Settings.Depth = 1
|
||||||
|
p.Settings.Filter = "tree:0"
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute provides the implementation of the plugin.
|
||||||
|
func (p *Plugin) Execute() error {
|
||||||
|
cmds := make([]*execabs.Cmd, 0)
|
||||||
|
|
||||||
|
if err := os.Setenv("GIT_TERMINAL_PROMPT", "0"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// prevents git-lfs from retrieving any LFS files
|
||||||
|
if err := os.Setenv("GIT_LFS_SKIP_SMUDGE", "1"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle init
|
||||||
|
initPath := filepath.Join(p.Settings.WorkDir, ".git")
|
||||||
|
|
||||||
|
if err := os.MkdirAll(p.Settings.WorkDir, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:nestif
|
||||||
|
if _, err := os.Stat(initPath); os.IsNotExist(err) {
|
||||||
|
if err := p.execCmd(git.Init(p.Settings.Repo), new(bytes.Buffer)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Settings.UseSSH {
|
||||||
|
cmds = append(cmds, git.RemoteAdd(p.Settings.Repo.RemoteSSH))
|
||||||
|
if p.Settings.SSHKey != "" {
|
||||||
|
cmds = append(cmds, git.ConfigSSHCommand(p.Settings.SSHKey))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cmds = append(cmds, git.RemoteAdd(p.Settings.Repo.RemoteURL))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmds = append(cmds, git.ConfigSSLVerify(p.Settings.Repo))
|
||||||
|
|
||||||
|
if err := git.WriteNetrc(p.Settings.Netrc.Machine, p.Settings.Netrc.Login, p.Settings.Netrc.Password); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle clone
|
||||||
|
|
||||||
|
if p.Settings.Repo.CommitSha == "" {
|
||||||
|
// fetch and checkout by ref
|
||||||
|
log.Info().Msg("no commit information: using head checkout")
|
||||||
|
|
||||||
|
cmds = append(cmds, git.FetchSource(p.Settings.Repo.CommitRef, p.Settings.Tags, p.Settings.Depth, p.Settings.Filter))
|
||||||
|
cmds = append(cmds, git.CheckoutHead())
|
||||||
|
} else {
|
||||||
|
cmds = append(cmds, git.FetchSource(p.Settings.Repo.CommitSha, p.Settings.Tags, p.Settings.Depth, p.Settings.Filter))
|
||||||
|
cmds = append(cmds, git.CheckoutSha(p.Settings.Repo))
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, submoduleURL := range p.Settings.Repo.Submodules {
|
||||||
|
cmds = append(cmds, git.ConfigRemapSubmodule(name, submoduleURL))
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Settings.Recursive {
|
||||||
|
cmds = append(cmds, git.SubmoduleUpdate(p.Settings.Repo))
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Settings.Lfs {
|
||||||
|
cmds = append(cmds, git.FetchLFS())
|
||||||
|
cmds = append(cmds, git.CheckoutLFS())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cmd := range cmds {
|
||||||
|
log.Debug().Msgf("+ %s", strings.Join(cmd.Args, " "))
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
err := p.execCmd(cmd, buf)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case err != nil && shouldRetry(buf.String()):
|
||||||
|
backoffOps := func() error {
|
||||||
|
// copy the original command
|
||||||
|
//nolint:gosec
|
||||||
|
retry := execabs.Command(cmd.Args[0], cmd.Args[1:]...)
|
||||||
|
retry.Dir = cmd.Dir
|
||||||
|
retry.Env = cmd.Env
|
||||||
|
retry.Stdout = os.Stdout
|
||||||
|
retry.Stderr = os.Stderr
|
||||||
|
|
||||||
|
trace(cmd)
|
||||||
|
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
backoffLog := func(err error, delay time.Duration) {
|
||||||
|
log.Error().Msgf("failed to find remote ref: %v: retry in %s", err, delay.Truncate(time.Second))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := backoff.RetryNotify(backoffOps, newBackoff(daemonBackoffMaxRetries), backoffLog); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case err != nil:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Plugin) FlagsFromContext() error {
|
||||||
|
submodules, ok := p.Context.Generic("submodule-override").(*types.MapFlag)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("%w: failed to read submodule-override input", ErrTypeAssertionFailed)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Settings.Repo.Submodules = submodules.Get()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Plugin) execCmd(cmd *execabs.Cmd, buf *bytes.Buffer) error {
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
cmd.Stdout = io.MultiWriter(os.Stdout, buf)
|
||||||
|
cmd.Stderr = io.MultiWriter(os.Stderr, buf)
|
||||||
|
cmd.Dir = p.Settings.WorkDir
|
||||||
|
|
||||||
|
fmt.Println(cmd.Dir)
|
||||||
|
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
243
plugin/impl_test.go
Normal file
243
plugin/impl_test.go
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/thegeeklab/wp-git-clone/git"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testCommit struct {
|
||||||
|
name string
|
||||||
|
path string
|
||||||
|
clone string
|
||||||
|
event string
|
||||||
|
commit string
|
||||||
|
ref string
|
||||||
|
file string
|
||||||
|
data string
|
||||||
|
dataSize int64
|
||||||
|
recursive bool
|
||||||
|
lfs bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestClone tests the ability to clone a specific commit into
|
||||||
|
// a fresh, empty directory every time.
|
||||||
|
func TestClone(t *testing.T) {
|
||||||
|
for _, tt := range getCommits() {
|
||||||
|
dir := setup()
|
||||||
|
defer teardown(dir)
|
||||||
|
|
||||||
|
plugin := Plugin{
|
||||||
|
Settings: &Settings{
|
||||||
|
Repo: git.Repository{
|
||||||
|
RemoteURL: tt.clone,
|
||||||
|
CommitRef: tt.ref,
|
||||||
|
CommitSha: tt.commit,
|
||||||
|
},
|
||||||
|
Pipeline: Pipeline{
|
||||||
|
Event: tt.event,
|
||||||
|
},
|
||||||
|
WorkDir: filepath.Join(dir, tt.path),
|
||||||
|
Recursive: tt.recursive,
|
||||||
|
Lfs: tt.lfs,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := plugin.Execute(); err != nil {
|
||||||
|
t.Errorf("Expected successful clone. Got error. %s.", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.data != "" {
|
||||||
|
data := readFile(plugin.Settings.WorkDir, tt.file)
|
||||||
|
if data != tt.data {
|
||||||
|
t.Errorf("Expected %s to contain [%s]. Got [%s].", tt.file, tt.data, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.dataSize != 0 {
|
||||||
|
size := getFileSize(plugin.Settings.WorkDir, tt.file)
|
||||||
|
if size != tt.dataSize {
|
||||||
|
t.Errorf("Expected %s size to be [%d]. Got [%d].", tt.file, tt.dataSize, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCloneNonEmpty tests the ability to clone a specific commit into
|
||||||
|
// a non-empty directory. This is useful if the git workspace is cached
|
||||||
|
// and re-stored for every workflow.
|
||||||
|
func TestCloneNonEmpty(t *testing.T) {
|
||||||
|
dir := setup()
|
||||||
|
defer teardown(dir)
|
||||||
|
|
||||||
|
for _, tt := range getCommits() {
|
||||||
|
plugin := Plugin{
|
||||||
|
Settings: &Settings{
|
||||||
|
Repo: git.Repository{
|
||||||
|
RemoteURL: tt.clone,
|
||||||
|
CommitRef: tt.ref,
|
||||||
|
CommitSha: tt.commit,
|
||||||
|
},
|
||||||
|
Pipeline: Pipeline{
|
||||||
|
Event: tt.event,
|
||||||
|
},
|
||||||
|
WorkDir: filepath.Join(dir, tt.path),
|
||||||
|
Recursive: tt.recursive,
|
||||||
|
Lfs: tt.lfs,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(plugin.Settings.Repo.CommitSha, tt.commit, fmt.Sprintf("%q", tt.data))
|
||||||
|
|
||||||
|
if err := plugin.Execute(); err != nil {
|
||||||
|
t.Errorf("Expected successful clone. Got error. %s.", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.data != "" {
|
||||||
|
data := readFile(plugin.Settings.WorkDir, tt.file)
|
||||||
|
if data != tt.data {
|
||||||
|
t.Errorf("Expected %s to contain [%q]. Got [%q].", tt.file, tt.data, data)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.dataSize != 0 {
|
||||||
|
size := getFileSize(plugin.Settings.WorkDir, tt.file)
|
||||||
|
if size != tt.dataSize {
|
||||||
|
t.Errorf("Expected %s size to be [%d]. Got [%d].", tt.file, tt.dataSize, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function that will setup a temporary workspace
|
||||||
|
// to which we can clone the repositroy.
|
||||||
|
func setup() string {
|
||||||
|
dir, _ := os.MkdirTemp("/tmp", "plugin_git_test_")
|
||||||
|
_ = os.Mkdir(dir, os.ModePerm)
|
||||||
|
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to delete the temporary workspace.
|
||||||
|
func teardown(dir string) {
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to read a file in the temporary worskapce.
|
||||||
|
func readFile(dir, file string) string {
|
||||||
|
filename := filepath.Join(dir, file)
|
||||||
|
fmt.Println(filename)
|
||||||
|
data, _ := os.ReadFile(filename)
|
||||||
|
|
||||||
|
return string(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFileSize(dir, file string) int64 {
|
||||||
|
filename := filepath.Join(dir, file)
|
||||||
|
fi, _ := os.Stat(filename)
|
||||||
|
|
||||||
|
return fi.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCommits() []testCommit {
|
||||||
|
return []testCommit{
|
||||||
|
{
|
||||||
|
name: "first commit",
|
||||||
|
path: "octocat/Hello-World",
|
||||||
|
clone: "https://github.com/octocat/Hello-World.git",
|
||||||
|
event: "push",
|
||||||
|
commit: "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e",
|
||||||
|
ref: "refs/heads/master",
|
||||||
|
file: "README",
|
||||||
|
data: "Hello World!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "head commit",
|
||||||
|
path: "octocat/Hello-World",
|
||||||
|
clone: "https://github.com/octocat/Hello-World.git",
|
||||||
|
event: "push",
|
||||||
|
commit: "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d",
|
||||||
|
ref: "refs/heads/master",
|
||||||
|
file: "README",
|
||||||
|
data: "Hello World!\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "pull request commit",
|
||||||
|
path: "octocat/Hello-World",
|
||||||
|
clone: "https://github.com/octocat/Hello-World.git",
|
||||||
|
event: "pull_request",
|
||||||
|
commit: "762941318ee16e59dabbacb1b4049eec22f0d303",
|
||||||
|
ref: "refs/pull/6/merge",
|
||||||
|
file: "README",
|
||||||
|
data: "Hello World!\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "branch",
|
||||||
|
path: "octocat/Hello-World",
|
||||||
|
clone: "https://github.com/octocat/Hello-World.git",
|
||||||
|
event: "push",
|
||||||
|
commit: "b3cbd5bbd7e81436d2eee04537ea2b4c0cad4cdf",
|
||||||
|
ref: "refs/heads/test",
|
||||||
|
file: "CONTRIBUTING.md",
|
||||||
|
data: "## Contributing\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "tags",
|
||||||
|
path: "github/mime-types",
|
||||||
|
clone: "https://github.com/github/mime-types.git",
|
||||||
|
event: "tag",
|
||||||
|
commit: "bf68d60215a167c935bc5976b7d06a7ffb290926",
|
||||||
|
ref: "refs/tags/v1.17",
|
||||||
|
file: ".gitignore",
|
||||||
|
data: "*.swp\n*~\n.rake_tasks~\nhtml\ndoc\npkg\npublish\ncoverage\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "submodules",
|
||||||
|
path: "test-assets/woodpecker-git-test-submodule",
|
||||||
|
clone: "https://github.com/test-assets/woodpecker-git-test-submodule.git",
|
||||||
|
event: "push",
|
||||||
|
commit: "cc020eb6aaa601c13ca7b0d5db9d1ca694e7a003",
|
||||||
|
ref: "refs/heads/main",
|
||||||
|
file: "Hello-World/README",
|
||||||
|
data: "Hello World!\n",
|
||||||
|
recursive: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "checkout with ref only",
|
||||||
|
path: "octocat/Hello-World",
|
||||||
|
clone: "https://github.com/octocat/Hello-World.git",
|
||||||
|
event: "push",
|
||||||
|
// commit: "a11fb45a696bf1d696fc9ab2c733f8f123aa4cf5",
|
||||||
|
ref: "pull/2403/head",
|
||||||
|
file: "README",
|
||||||
|
data: "Hello World!\n\nsomething is changed!\n",
|
||||||
|
},
|
||||||
|
// test lfs, please do not change order, otherwise TestCloneNonEmpty will fail ###
|
||||||
|
{
|
||||||
|
name: "checkout with lfs skip",
|
||||||
|
path: "test-assets/woodpecker-git-test-lfs",
|
||||||
|
clone: "https://github.com/test-assets/woodpecker-git-test-lfs.git",
|
||||||
|
event: "push",
|
||||||
|
commit: "69d4dadb4c2899efb73c0095bb58a6454d133cef",
|
||||||
|
ref: "refs/heads/main",
|
||||||
|
file: "4M.bin",
|
||||||
|
dataSize: 132,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "checkout with lfs",
|
||||||
|
path: "test-assets/woodpecker-git-test-lfs",
|
||||||
|
clone: "https://github.com/test-assets/woodpecker-git-test-lfs.git",
|
||||||
|
event: "push",
|
||||||
|
commit: "69d4dadb4c2899efb73c0095bb58a6454d133cef",
|
||||||
|
ref: "refs/heads/main",
|
||||||
|
file: "4M.bin",
|
||||||
|
dataSize: 4194304,
|
||||||
|
lfs: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
56
plugin/plugin.go
Normal file
56
plugin/plugin.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright (c) 2023, Robert Kaussow <mail@thegeeklab.de>
|
||||||
|
|
||||||
|
// Use of this source code is governed by an Apache 2.0 license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/thegeeklab/wp-git-clone/git"
|
||||||
|
wp "github.com/thegeeklab/wp-plugin-go/plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Plugin implements provide the plugin.
|
||||||
|
type Plugin struct {
|
||||||
|
*wp.Plugin
|
||||||
|
Settings *Settings
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pipeline struct {
|
||||||
|
Event string
|
||||||
|
Number int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Netrc struct {
|
||||||
|
Machine string
|
||||||
|
Login string
|
||||||
|
Password string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings for the plugin.
|
||||||
|
type Settings struct {
|
||||||
|
Depth int
|
||||||
|
Recursive bool
|
||||||
|
Tags bool
|
||||||
|
Lfs bool
|
||||||
|
Partial bool
|
||||||
|
Filter string
|
||||||
|
UseSSH bool
|
||||||
|
SSHKey string
|
||||||
|
WorkDir string
|
||||||
|
|
||||||
|
Pipeline Pipeline
|
||||||
|
Netrc Netrc
|
||||||
|
Repo git.Repository
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(options wp.Options, settings *Settings) *Plugin {
|
||||||
|
p := &Plugin{}
|
||||||
|
|
||||||
|
options.Execute = p.run
|
||||||
|
|
||||||
|
p.Plugin = wp.New(options)
|
||||||
|
p.Settings = settings
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
28
plugin/utils.go
Normal file
28
plugin/utils.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cenkalti/backoff/v4"
|
||||||
|
"golang.org/x/sys/execabs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// shouldRetry returns true if the command should be re-executed. Currently
|
||||||
|
// this only returns true if the remote ref does not exist.
|
||||||
|
func shouldRetry(s string) bool {
|
||||||
|
return strings.Contains(s, "find remote ref")
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBackoff(maxRetries uint64) backoff.BackOff {
|
||||||
|
b := backoff.NewExponentialBackOff()
|
||||||
|
b.InitialInterval = daemonBackoffInitialInterval
|
||||||
|
b.Multiplier = daemonBackoffMultiplier
|
||||||
|
|
||||||
|
return backoff.WithMaxRetries(b, maxRetries)
|
||||||
|
}
|
||||||
|
|
||||||
|
func trace(cmd *execabs.Cmd) {
|
||||||
|
fmt.Fprintf(os.Stdout, "+ %s\n", strings.Join(cmd.Args, " "))
|
||||||
|
}
|
4
renovate.json
Normal file
4
renovate.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": ["github>thegeeklab/renovate-presets:golang"]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user