Merge pull request #16 from xoxys/master

rewrite plugin to work with drone 0.8+
This commit is contained in:
Thomas Boerger
2019-02-13 08:51:23 +01:00
committed by GitHub
29 changed files with 971 additions and 557 deletions
+2
View File
@@ -0,0 +1,2 @@
*
!release/
+192
View File
@@ -0,0 +1,192 @@
local PipelineTesting = {
kind: "pipeline",
name: "testing",
platform: {
os: "linux",
arch: "amd64",
},
services: [
{
name: "pypiserver",
image: "pypiserver/pypiserver",
pull: "always",
entrypoint: [
"pypi-server",
"-P",
".",
"-a",
".",
"-p",
"8080",
"/data/packages"
],
},
],
steps: [
{
name: "vet",
image: "golang:1.11",
pull: "always",
environment: {
GO111MODULE: "on",
},
commands: [
"go vet ./...",
],
},
{
name: "test",
image: "golang:1.11-alpine",
pull: "always",
environment: {
GO111MODULE: "on",
PLUGIN_REPOSITORY: "http://pypiserver:8080/",
PLUGIN_DISTRIBUTIONS: "sdist",
PLUGIN_USERNAME: "demo",
PLUGIN_PASSWORD: "demo",
},
commands: [
"apk --no-cache add -U python3 git",
"pip3 install --no-cache-dir --upgrade pip setuptools wheel six twine",
"go test -cover ./...",
],
},
],
trigger: {
branch: [ "master" ],
},
};
local PipelineBuild(os="linux", arch="amd64") = {
kind: "pipeline",
name: os + "-" + arch,
platform: {
os: os,
arch: arch,
},
steps: [
{
name: "build-push",
image: "golang:1.11",
pull: "always",
environment: {
CGO_ENABLED: "0",
GO111MODULE: "on",
},
commands: [
"go build -v -ldflags \"-X main.build=${DRONE_BUILD_NUMBER}\" -a -o release/" + os + "/" + arch + "/drone-pypi",
],
when: {
event: [ "push", "pull_request" ],
},
},
{
name: "build-tag",
image: "golang:1.11",
pull: "always",
environment: {
CGO_ENABLED: "0",
GO111MODULE: "on",
},
commands: [
"go build -v -ldflags \"-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}\" -a -o release/" + os + "/" + arch + "/drone-pypi",
],
when: {
event: [ "tag" ],
},
},
{
name: "executable",
image: "golang:1.11",
pull: "always",
commands: [
"./release/" + os + "/" + arch + "/drone-pypi --help",
],
},
{
name: "dryrun",
image: "plugins/docker:" + os + "-" + arch,
pull: "always",
settings: {
dry_run: true,
tags: os + "-" + arch,
dockerfile: "docker/Dockerfile." + os + "." + arch,
repo: "plugins/pypi",
username: { "from_secret": "docker_username" },
password: { "from_secret": "docker_password" },
},
when: {
event: [ "pull_request" ],
},
},
{
name: "publish",
image: "plugins/docker:" + os + "-" + arch,
pull: "always",
settings: {
auto_tag: true,
auto_tag_suffix: os + "-" + arch,
dockerfile: "docker/Dockerfile." + os + "." + arch,
repo: "plugins/pypi",
username: { "from_secret": "docker_username" },
password: { "from_secret": "docker_password" },
},
when: {
event: [ "push", "tag" ],
},
},
],
depends_on: [
"testing",
],
trigger: {
branch: [ "master" ],
},
};
local PipelineNotifications = {
kind: "pipeline",
name: "notifications",
platform: {
os: "linux",
arch: "amd64",
},
steps: [
{
name: "manifest",
image: "plugins/manifest:1",
pull: "always",
settings: {
username: { "from_secret": "docker_username" },
password: { "from_secret": "docker_password" },
spec: "docker/manifest.tmpl",
ignore_missing: true,
},
},
{
name: "microbadger",
image: "plugins/webhook:1",
pull: "always",
settings: {
url: { "from_secret": "microbadger_url" },
},
},
],
depends_on: [
"linux-amd64",
"linux-arm64",
"linux-arm",
],
trigger: {
branch: [ "master" ],
event: [ "push", "tag" ],
},
};
[
PipelineTesting,
PipelineBuild("linux", "amd64"),
PipelineBuild("linux", "arm64"),
PipelineBuild("linux", "arm"),
PipelineNotifications,
]
-1
View File
@@ -1 +0,0 @@
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.qT1HwNOvyKOcybO375AFxDGhmCaT9y3hIX3lOo3whybdcU-sDbVPyeN4DGNFQ9wXETOinGRm76LogzL6C1buMz5AccsQZMheYC-kfvBSnI2l63UwEu7zCkIrp1J1Frd0-vuoaOOih4Qr64u_N6lDmMYbayKvAB1wLp73FIzQexJf1bc8GR_cKyzA4vK9MrIZynD8jpnJx3bvq6l-mCxZl_OtJaZMzaNEe5w-NiWmoxfmhWMr06_hdoPf7O8cp_QFCSbY0CfDLIUrj6AwD6CeL0UbGIED9Ol-b5CCvFJ-u3rbYIp5GaIWCIMWz8v9ERVr1NZDQ8nb8hu8qNt5Uq5qEw.b8x12T3ociB4416-.PlWIfdFtneRvnYGtEyaDENhR-Zq83SQSnQjRMy2llv2y7efeBhLHsq1O1sT_VaA_MJzh7eQTPPIMZgNiRgO_OINjZLDmNlr-f4fzRzk7NAntlbH46J1p5IJPnXv1lQu0YJPfbLlx9qiy6DQHKkhTOInVwOkTwahTT_2eE5Rs2vp4zgV9oEqdCkc0knIqr-eDMl3E1MbQ4qbSDPCLL5V4WuiYCXOak8PmOKyiFuYWpAdaovyOz0gwjUAFxNA-ubU7m1Xpi_E-GNkPxATtCIMYgNr2f3pQGdsrSZnRCtBvsuXJqMyZ8dU9rxr--fY65dS26y2y4KC_6A03Uh-U4W2bYvrMuWeDifgyOoh7dCM2RWGQtuZJ3XfW2j86enVzk5m5FBEq7w.bogB-GosDieE9QNTSxqUbw
+325 -34
View File
@@ -1,38 +1,329 @@
build:
image: golang:1.5
environment:
- GO15VENDOREXPERIMENT=1
- GOOS=linux
- GOARCH=amd64
- CGO_ENABLED=0
- DRONE_PYPI_PATH=testdata
- DRONE_PYPI_REPOSITORY=http://localhost:8000
- DRONE_PYPI_DISTRIBUTIONS=sdist
---
kind: pipeline
name: testing
platform:
os: linux
arch: amd64
steps:
- name: vet
pull: always
image: golang:1.11
commands:
- apt-get update && apt-get install -y python-setuptools
- go get
- go build
- go test -cover
- go vet ./...
environment:
GO111MODULE: on
compose:
simplepypi:
image: msteinert/simplepypi
pull: true
- name: test
pull: always
image: golang:1.11-alpine
commands:
- apk --no-cache add -U python3 git
- pip3 install --no-cache-dir --upgrade pip setuptools wheel six twine
- go test -cover ./...
environment:
GO111MODULE: on
PLUGIN_DISTRIBUTIONS: sdist
PLUGIN_PASSWORD: demo
PLUGIN_REPOSITORY: http://pypiserver:8080/
PLUGIN_USERNAME: demo
publish:
docker:
username: drone
password: $$DOCKER_PASS
email: $$DOCKER_EMAIL
repo: plugins/drone-pypi
when:
branch: master
services:
- name: pypiserver
pull: always
image: pypiserver/pypiserver
entrypoint:
- pypi-server
- -P
- .
- -a
- .
- -p
- 8080
- /data/packages
plugin:
name: Pypi
desc: Publish a package to the Python package index.
type: publish
image: plugins/drone-pypi
labels:
- publish
- python
trigger:
branch:
- master
---
kind: pipeline
name: linux-amd64
platform:
os: linux
arch: amd64
steps:
- name: build-push
pull: always
image: golang:1.11
commands:
- "go build -v -ldflags \"-X main.build=${DRONE_BUILD_NUMBER}\" -a -o release/linux/amd64/drone-pypi"
environment:
CGO_ENABLED: 0
GO111MODULE: on
when:
event:
- push
- pull_request
- name: build-tag
pull: always
image: golang:1.11
commands:
- "go build -v -ldflags \"-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}\" -a -o release/linux/amd64/drone-pypi"
environment:
CGO_ENABLED: 0
GO111MODULE: on
when:
event:
- tag
- name: executable
pull: always
image: golang:1.11
commands:
- ./release/linux/amd64/drone-pypi --help
- name: dryrun
pull: always
image: plugins/docker:linux-amd64
settings:
dockerfile: docker/Dockerfile.linux.amd64
dry_run: true
password:
from_secret: docker_password
repo: plugins/pypi
tags: linux-amd64
username:
from_secret: docker_username
when:
event:
- pull_request
- name: publish
pull: always
image: plugins/docker:linux-amd64
settings:
auto_tag: true
auto_tag_suffix: linux-amd64
dockerfile: docker/Dockerfile.linux.amd64
password:
from_secret: docker_password
repo: plugins/pypi
username:
from_secret: docker_username
when:
event:
- push
- tag
trigger:
branch:
- master
depends_on:
- testing
---
kind: pipeline
name: linux-arm64
platform:
os: linux
arch: arm64
steps:
- name: build-push
pull: always
image: golang:1.11
commands:
- "go build -v -ldflags \"-X main.build=${DRONE_BUILD_NUMBER}\" -a -o release/linux/arm64/drone-pypi"
environment:
CGO_ENABLED: 0
GO111MODULE: on
when:
event:
- push
- pull_request
- name: build-tag
pull: always
image: golang:1.11
commands:
- "go build -v -ldflags \"-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}\" -a -o release/linux/arm64/drone-pypi"
environment:
CGO_ENABLED: 0
GO111MODULE: on
when:
event:
- tag
- name: executable
pull: always
image: golang:1.11
commands:
- ./release/linux/arm64/drone-pypi --help
- name: dryrun
pull: always
image: plugins/docker:linux-arm64
settings:
dockerfile: docker/Dockerfile.linux.arm64
dry_run: true
password:
from_secret: docker_password
repo: plugins/pypi
tags: linux-arm64
username:
from_secret: docker_username
when:
event:
- pull_request
- name: publish
pull: always
image: plugins/docker:linux-arm64
settings:
auto_tag: true
auto_tag_suffix: linux-arm64
dockerfile: docker/Dockerfile.linux.arm64
password:
from_secret: docker_password
repo: plugins/pypi
username:
from_secret: docker_username
when:
event:
- push
- tag
trigger:
branch:
- master
depends_on:
- testing
---
kind: pipeline
name: linux-arm
platform:
os: linux
arch: arm
steps:
- name: build-push
pull: always
image: golang:1.11
commands:
- "go build -v -ldflags \"-X main.build=${DRONE_BUILD_NUMBER}\" -a -o release/linux/arm/drone-pypi"
environment:
CGO_ENABLED: 0
GO111MODULE: on
when:
event:
- push
- pull_request
- name: build-tag
pull: always
image: golang:1.11
commands:
- "go build -v -ldflags \"-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}\" -a -o release/linux/arm/drone-pypi"
environment:
CGO_ENABLED: 0
GO111MODULE: on
when:
event:
- tag
- name: executable
pull: always
image: golang:1.11
commands:
- ./release/linux/arm/drone-pypi --help
- name: dryrun
pull: always
image: plugins/docker:linux-arm
settings:
dockerfile: docker/Dockerfile.linux.arm
dry_run: true
password:
from_secret: docker_password
repo: plugins/pypi
tags: linux-arm
username:
from_secret: docker_username
when:
event:
- pull_request
- name: publish
pull: always
image: plugins/docker:linux-arm
settings:
auto_tag: true
auto_tag_suffix: linux-arm
dockerfile: docker/Dockerfile.linux.arm
password:
from_secret: docker_password
repo: plugins/pypi
username:
from_secret: docker_username
when:
event:
- push
- tag
trigger:
branch:
- master
depends_on:
- testing
---
kind: pipeline
name: notifications
platform:
os: linux
arch: amd64
steps:
- name: manifest
pull: always
image: plugins/manifest:1
settings:
ignore_missing: true
password:
from_secret: docker_password
spec: docker/manifest.tmpl
username:
from_secret: docker_username
- name: microbadger
pull: always
image: plugins/webhook:1
settings:
url:
from_secret: microbadger_url
trigger:
branch:
- master
event:
- push
- tag
depends_on:
- linux-amd64
- linux-arm64
- linux-arm
...
+9
View File
@@ -0,0 +1,9 @@
<!-- PLEASE READ BEFORE DELETING
Bugs or Issues? Due to the high number of false positive issues we receive,
please do not create a GitHub issue until you have discussed and verified
with community support at:
https://discourse.drone.io/
-->
+75
View File
@@ -0,0 +1,75 @@
repository:
name: drone-pypi
description: Drone plugin to publish python packages to PyPi
homepage: http://plugins.drone.io/drone-plugins/drone-pypi
topics: drone, drone-plugin
private: false
has_issues: true
has_wiki: false
has_downloads: false
default_branch: master
allow_squash_merge: true
allow_merge_commit: true
allow_rebase_merge: true
labels:
- name: bug
color: d73a4a
description: Something isn't working
- 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: renovate
color: e99695
description: Automated action from Renovate
- name: wontfix
color: ffffff
description: This will not be worked on
teams:
- name: Admins
permission: admin
- name: Captain
permission: admin
- name: Maintainers
permission: push
branches:
- name: master
protection:
required_pull_request_reviews:
required_approving_review_count: 1
dismiss_stale_reviews: false
require_code_owner_reviews: false
dismissal_restrictions:
teams:
- Admins
- Captain
required_status_checks:
strict: true
contexts:
- continuous-integration/drone/pr
enforce_admins: false
restrictions:
users: []
teams:
- Admins
- Captain
+4
View File
@@ -23,4 +23,8 @@ _testmain.go
*.test
*.prof
release/
vendor/
coverage.out
drone-pypi
-19
View File
@@ -1,19 +0,0 @@
Use the PyPI plugin to deploy a Python package to a PyPI server.
* `repository` - The repository name (optional)
* `username` - The username to login with (optional)
* `password` - A password to login with (optional)
* `distributions` - A list of distribution types to deploy (optional)
The following is an example configuration for your .drone.yml:
```yaml
publish:
pypi:
repository: https://pypi.python.org/pypi
username: guido
password: secret
distributions:
- sdist
- bdist_wheel
```
-15
View File
@@ -1,15 +0,0 @@
FROM alpine:3.2
RUN apk add -U \
ca-certificates \
py-pip \
python \
&& rm -rf /var/cache/apk/* \
&& pip install --no-cache-dir --upgrade \
pip \
setuptools \
wheel
ADD drone-pypi /bin/
ENTRYPOINT ["/bin/drone-pypi"]
-1
View File
@@ -199,4 +199,3 @@
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.
-35
View File
@@ -1,35 +0,0 @@
[people]
[people.bradrydzewski]
name = "Brad Rydzewski"
email = "brad@drone.io"
login = "bradrydzewski"
[people.Bugagazavr]
login = "Bugagazavr"
[people.donny-dont]
name = "Don Olmstead"
email = "donny-dont@gmail.com"
login = "donny-dont"
[people.gtaylor]
name = Greg Taylor
email = ""
login = "gtaylor"
[people.jackspirou]
name = "Jack Spirou"
email = ""
login = "jackspirou"
[people.msteinert]
name = "Mike Steinert"
email = ""
login = "msteinert"
[people.nlf]
name = "Nathan LaFreniere"
email = ""
login = "nlf"
[people.tboerger]
name = "Thomas Boerger"
email = ""
login = "tboerger"
[org]
[org.core]
people = ["bradrydzewski", "Bugagazavr", "donny-dont", "gtaylor", "jackspirou", "msteinert", "nlf", "tboerger"]
+35 -56
View File
@@ -1,68 +1,47 @@
# drone-pypi
[![Build Status](http://beta.drone.io/api/badges/drone-plugins/drone-pypi/status.svg)](http://beta.drone.io/drone-plugins/drone-pypi)
[![](https://badge.imagelayers.io/plugins/drone-pypi:latest.svg)](https://imagelayers.io/?images=plugins/drone-pypi:latest 'Get your own badge on imagelayers.io')
[![Build Status](http://cloud.drone.io/api/badges/drone-plugins/drone-pypi/status.svg)](http://cloud.drone.io/drone-plugins/drone-pypi)
[![Gitter chat](https://badges.gitter.im/drone/drone.png)](https://gitter.im/drone/drone)
[![Join the discussion at https://discourse.drone.io](https://img.shields.io/badge/discourse-forum-orange.svg)](https://discourse.drone.io)
[![Drone questions at https://stackoverflow.com](https://img.shields.io/badge/drone-stackoverflow-orange.svg)](https://stackoverflow.com/questions/tagged/drone.io)
[![](https://images.microbadger.com/badges/image/plugins/pypi.svg)](https://microbadger.com/images/plugins/pypi "Get your own image badge on microbadger.com")
[![Go Doc](https://godoc.org/github.com/drone-plugins/drone-pypi?status.svg)](http://godoc.org/github.com/drone-plugins/drone-pypi)
[![Go Report](https://goreportcard.com/badge/github.com/drone-plugins/drone-pypi)](https://goreportcard.com/report/github.com/drone-plugins/drone-pypi)
Drone plugin for publishing to the Python package index
Drone Plugin for PyPi publishing with [twine](https://pypi.org/project/twine/). For the usage information and a listing of the available options please take a look at [the docs](http://plugins.drone.io/drone-plugins/drone-pypi/).
## Usage
## Build
Upload a source distribution to PyPI
Build the binary with the following commands:
```sh
./drone-pypi <<EOF
{
"workspace": {
"path": "/drone/my-module-py"
}
"vargs": {
"username": "guido",
"password": "secret"
}
}
EOF
```Shell
export GOOS=linux
export GOARCH=amd64
export CGO_ENABLED=0
export GO111MODULE=on
go build -v -a -tags netgo -o release/linux/amd64/drone-pypi
```
Upload a source distribution and a wheel to PyPI
```sh
./drone-pypi <<EOF
{
"workspace": {
"path": "/drone/my-module-py"
}
"vargs": {
"distributions": ["sdist", "bdist_wheel"],
"username": "guido",
"password": "secret"
}
}
EOF
```
Upload a source distribution to a private PyPI server, e.g. [simplepypi][]
```sh
./drone-pypi <<EOF
{
"workspace": {
"path": "/drone/my-module-py"
}
"vargs": {
"repository": "https://pypi.example.com"
}
}
EOF
```
[simplepypi]: https://github.com/steiza/simplepypi
## Docker
Build the Docker container using the `netgo` build tag to eliminate
the CGO dependency:
Build the Docker image with the following commands:
```sh
CGO_ENABLED=0 go build -a -tags netgo
docker build --rm=true -t plugins/drone-pypi .
```Shell
docker build \
--label org.label-schema.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--label org.label-schema.vcs-ref=$(git rev-parse --short HEAD) \
--file docker/Dockerfile.linux.amd64 --tag plugins/pypi .
```
## Usage
```Shell
docker run --rm \
-e PLUGIN_USERNAME=jdoe \
-e PLUGIN_PASSWORD=my_secret \
-e PLUGIN_SKIP_BUILD=false \
-v $(pwd):$(pwd) \
-w $(pwd) \
plugins/pypi
```
+13
View File
@@ -0,0 +1,13 @@
FROM plugins/base:linux-amd64
LABEL maintainer="Drone.IO Community <drone-dev@googlegroups.com>" \
org.label-schema.name="Drone PyPi" \
org.label-schema.vendor="Drone.IO Community" \
org.label-schema.schema-version="1.0"
RUN apk add -U ca-certificates python3 && \
rm -rf /var/cache/apk/* && \
pip3 install --no-cache-dir --upgrade pip setuptools wheel six twine
ADD release/linux/amd64/drone-pypi /bin/
ENTRYPOINT ["/bin/drone-pypi"]
+13
View File
@@ -0,0 +1,13 @@
FROM plugins/base:linux-arm
LABEL maintainer="Drone.IO Community <drone-dev@googlegroups.com>" \
org.label-schema.name="Drone PyPi" \
org.label-schema.vendor="Drone.IO Community" \
org.label-schema.schema-version="1.0"
RUN apk add -U ca-certificates python3 && \
rm -rf /var/cache/apk/* && \
pip3 install --no-cache-dir --upgrade pip setuptools wheel six twine
ADD release/linux/arm/drone-pypi /bin/
ENTRYPOINT ["/bin/drone-pypi"]
+13
View File
@@ -0,0 +1,13 @@
FROM plugins/base:linux-arm64
LABEL maintainer="Drone.IO Community <drone-dev@googlegroups.com>" \
org.label-schema.name="Drone PyPi" \
org.label-schema.vendor="Drone.IO Community" \
org.label-schema.schema-version="1.0"
RUN apk add -U ca-certificates python3 && \
rm -rf /var/cache/apk/* && \
pip3 install --no-cache-dir --upgrade pip setuptools wheel six twine
ADD release/linux/arm64/drone-pypi /bin/
ENTRYPOINT ["/bin/drone-pypi"]
+25
View File
@@ -0,0 +1,25 @@
image: plugins/pypi:{{#if build.tag}}{{trimPrefix build.tag "v"}}{{else}}latest{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
-
image: plugins/pypi:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}linux-amd64
platform:
architecture: amd64
os: linux
-
image: plugins/pypi:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}linux-arm64
platform:
architecture: arm64
os: linux
variant: v8
-
image: plugins/pypi:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}linux-arm
platform:
architecture: arm
os: linux
variant: v7
+7
View File
@@ -0,0 +1,7 @@
module github.com/xoxys/plugin-pypi
require (
github.com/joho/godotenv v1.3.0
github.com/pkg/errors v0.8.1
github.com/urfave/cli v1.20.0
)
+6
View File
@@ -0,0 +1,6 @@
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-113
View File
@@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="110.4211"
height="109.8461"
id="svg2169"
sodipodi:version="0.32"
inkscape:version="0.45.1"
version="1.0"
sodipodi:docbase="/home/bene/Desktop"
sodipodi:docname="dessin-1.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2171">
<linearGradient
id="linearGradient11301"
inkscape:collect="always">
<stop
id="stop11303"
offset="0"
style="stop-color:#ffe052;stop-opacity:1" />
<stop
id="stop11305"
offset="1"
style="stop-color:#ffc331;stop-opacity:1" />
</linearGradient>
<linearGradient
gradientUnits="userSpaceOnUse"
y2="168.1012"
x2="147.77737"
y1="111.92053"
x1="89.136749"
id="linearGradient11307"
xlink:href="#linearGradient11301"
inkscape:collect="always" />
<linearGradient
id="linearGradient9515"
inkscape:collect="always">
<stop
id="stop9517"
offset="0"
style="stop-color:#387eb8;stop-opacity:1" />
<stop
id="stop9519"
offset="1"
style="stop-color:#366994;stop-opacity:1" />
</linearGradient>
<linearGradient
gradientUnits="userSpaceOnUse"
y2="131.85291"
x2="110.14919"
y1="77.070274"
x1="55.549179"
id="linearGradient9521"
xlink:href="#linearGradient9515"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.24748737"
inkscape:cx="-260.46312"
inkscape:cy="316.02744"
inkscape:document-units="px"
inkscape:current-layer="layer1"
width="131.10236px"
height="184.25197px"
inkscape:window-width="872"
inkscape:window-height="624"
inkscape:window-x="5"
inkscape:window-y="48" />
<metadata
id="metadata2174">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-473.36088,-251.72485)">
<g
id="g1894"
transform="translate(428.42338,184.2561)">
<path
style="opacity:1;color:#000000;fill:url(#linearGradient9521);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 99.75,67.46875 C 71.718268,67.468752 73.46875,79.625 73.46875,79.625 L 73.5,92.21875 L 100.25,92.21875 L 100.25,96 L 62.875,96 C 62.875,96 44.9375,93.965724 44.9375,122.25 C 44.937498,150.53427 60.59375,149.53125 60.59375,149.53125 L 69.9375,149.53125 L 69.9375,136.40625 C 69.9375,136.40625 69.433848,120.75 85.34375,120.75 C 101.25365,120.75 111.875,120.75 111.875,120.75 C 111.875,120.75 126.78125,120.99096 126.78125,106.34375 C 126.78125,91.696544 126.78125,82.125 126.78125,82.125 C 126.78125,82.124998 129.04443,67.46875 99.75,67.46875 z M 85,75.9375 C 87.661429,75.937498 89.8125,78.088571 89.8125,80.75 C 89.812502,83.411429 87.661429,85.5625 85,85.5625 C 82.338571,85.562502 80.1875,83.411429 80.1875,80.75 C 80.187498,78.088571 82.338571,75.9375 85,75.9375 z "
id="path8615" />
<path
id="path8620"
d="M 100.5461,177.31485 C 128.57784,177.31485 126.82735,165.1586 126.82735,165.1586 L 126.7961,152.56485 L 100.0461,152.56485 L 100.0461,148.7836 L 137.4211,148.7836 C 137.4211,148.7836 155.3586,150.81787 155.3586,122.53359 C 155.35861,94.249323 139.70235,95.252343 139.70235,95.252343 L 130.3586,95.252343 L 130.3586,108.37734 C 130.3586,108.37734 130.86226,124.03359 114.95235,124.03359 C 99.042448,124.03359 88.421098,124.03359 88.421098,124.03359 C 88.421098,124.03359 73.514848,123.79263 73.514848,138.43985 C 73.514848,153.08705 73.514848,162.6586 73.514848,162.6586 C 73.514848,162.6586 71.251668,177.31485 100.5461,177.31485 z M 115.2961,168.8461 C 112.63467,168.8461 110.4836,166.69503 110.4836,164.0336 C 110.4836,161.37217 112.63467,159.2211 115.2961,159.2211 C 117.95753,159.2211 120.1086,161.37217 120.1086,164.0336 C 120.10861,166.69503 117.95753,168.8461 115.2961,168.8461 z "
style="opacity:1;color:#000000;fill:url(#linearGradient11307);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.4 KiB

+56 -104
View File
@@ -1,122 +1,74 @@
package main
import (
"bufio"
"fmt"
"io"
"log"
"os"
"os/exec"
"path"
"strings"
"github.com/drone/drone-go/drone"
"github.com/drone/drone-go/plugin"
"github.com/urfave/cli"
_ "github.com/joho/godotenv/autoload"
)
// Params desribes how to upload a Python module to PyPI.
type Params struct {
Distributions []string `json:"distributions"`
Password *string `json:"password,omitempty"`
Repository *string `json:"repository,omitempty"`
Username *string `json:"username,omitempty"`
}
var build = "0" // build number set at compile-time
func main() {
w := drone.Workspace{}
v := Params{}
plugin.Param("workspace", &w)
plugin.Param("vargs", &v)
plugin.MustParse()
app := cli.NewApp()
app.Name = "pypi plugin"
app.Usage = "pypi publish plugin"
app.Action = run
app.Version = fmt.Sprintf("0.0.%s", build)
app.Flags = []cli.Flag{
err := v.Deploy(&w)
if err != nil {
log.Fatal(err)
cli.StringFlag{
Name: "repository",
Usage: "pypi repository URL",
Value: "https://upload.pypi.org/legacy/",
EnvVar: "PLUGIN_REPOSITORY",
},
cli.StringFlag{
Name: "username",
Usage: "pypi username",
Value: "guido",
EnvVar: "PLUGIN_USERNAME,PYPI_USERNAME",
},
cli.StringFlag{
Name: "password",
Usage: "pypi password",
Value: "secret",
EnvVar: "PLUGIN_PASSWORD,PYPI_PASSWORD",
},
cli.StringFlag{
Name: "setupfile",
Usage: "relative location of setup.py file",
Value: "setup.py",
EnvVar: "PLUGIN_SETUPFILE",
},
cli.StringSliceFlag{
Name: "distributions",
Usage: "distribution types to deploy",
EnvVar: "PLUGIN_DISTRIBUTIONS",
},
cli.BoolTFlag{
Name: "skip_build",
Usage: "skip build and only upload pre-build packages",
EnvVar: "PLUGIN_SKIP_BUILD",
},
}
app.Run(os.Args)
}
// Deploy creates a PyPI configuration file and uploads a module.
func (v *Params) Deploy(w *drone.Workspace) error {
err := v.CreateConfig()
if err != nil {
return err
func run(c *cli.Context) {
plugin := Plugin{
Repository: c.String("repository"),
Username: c.String("username"),
Password: c.String("password"),
SetupFile: c.String("setupfile"),
Distributions: c.StringSlice("distributions"),
SkipBuild: c.Bool("skip_build"),
}
err = v.UploadDist(w)
if err != nil {
return err
}
return nil
}
// CreateConfig creates a PyPI configuration file in the home directory of
// the current user.
func (v *Params) CreateConfig() error {
f, err := os.Create(path.Join(os.Getenv("HOME"), ".pypirc"))
if err != nil {
return err
if err := plugin.Exec(); err != nil {
fmt.Println(err)
os.Exit(1)
}
defer f.Close()
buf := bufio.NewWriter(f)
err = v.WriteConfig(buf)
if err != nil {
return err
}
buf.Flush()
return nil
}
// UploadDist executes a distutils command to upload a python module.
func (v *Params) UploadDist(w *drone.Workspace) error {
cmd := v.Upload()
cmd.Dir = w.Path
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
fmt.Println("$", strings.Join(cmd.Args, " "))
err := cmd.Run()
if err != nil {
return err
}
return nil
}
// WriteConfig writes a .pypirc to a supplied io.Writer.
func (v *Params) WriteConfig(w io.Writer) error {
repository := "https://pypi.python.org/pypi"
if v.Repository != nil {
repository = *v.Repository
}
username := "guido"
if v.Username != nil {
username = *v.Username
}
password := "secret"
if v.Password != nil {
password = *v.Password
}
_, err := io.WriteString(w, fmt.Sprintf(`[distutils]
index-servers =
pypi
[pypi]
repository: %s
username: %s
password: %s
`, repository, username, password))
return err
}
// Upload creates a distutils upload command.
func (v *Params) Upload() *exec.Cmd {
distributions := []string{"sdist"}
if len(v.Distributions) > 0 {
distributions = v.Distributions
}
args := []string{"setup.py"}
for i := range distributions {
args = append(args, distributions[i])
}
args = append(args, "upload")
args = append(args, "-r")
args = append(args, "pypi")
return exec.Command("python", args...)
}
-152
View File
@@ -1,152 +0,0 @@
package main
import (
"bytes"
"os"
"strings"
"testing"
"github.com/drone/drone-go/drone"
)
// TestPublish checks if this module can successfully publish a PyPI
// package. A simple module is included in the `testdata` directory.
//
// To run this test against the PyPI test server:
//
// 1. register a new account (https://wiki.python.org/moin/TestPyPI)
// 2. Export DRONE_PYPI_PATH, DRONE_PYPI_REPOSITORY, DRONE_PYPI_USERNAME,
// DRONE_PYPI_PASSWORD, and DRONE_PYPI_DISTRIBUTIONS
// 3. Run the test suite
//
// For example:
//
// $ export DRONE_PYPI_PATH=testdata
// $ export DRONE_PYPI_REPOSITORY=https://testpypi.python.org/pypi
// $ export DRONE_PYPI_USERNAME=drone_pypi_test
// $ export DRONE_PYPI_PASSWORD=$uper$ecretPassword
// $ export DRONE_PYPI_DISTRIBUTIONS=sdist
// $ go test -run TestPublish
//
// > NOTE: PyPI will refuse to upload the same version of a module twice,
// > however setup.py still returns zero to the shell so this appears as a
// > successful test.
func TestPublish(t *testing.T) {
w := drone.Workspace{Path: os.Getenv("DRONE_PYPI_PATH")}
repository := os.Getenv("DRONE_PYPI_REPOSITORY")
username := os.Getenv("DRONE_PYPI_USERNAME")
password := os.Getenv("DRONE_PYPI_PASSWORD")
v := Params{
Repository: &repository,
Username: &username,
Password: &password,
Distributions: strings.Split(os.Getenv("DRONE_PYPI_DISTRIBUTIONS"), " "),
}
if w.Path == "" {
t.Skip("DRONE_PYPI_PATH not set")
}
err := v.Deploy(&w)
if err != nil {
t.Error(err)
}
}
// TestConfig checks if a PyPI configuration file can be generated.
func TestConfig(t *testing.T) {
testdata := []struct {
repository *string
username *string
password *string
exp string
}{
{
nil,
nil,
nil,
`[distutils]
index-servers =
pypi
[pypi]
repository: https://pypi.python.org/pypi
username: guido
password: secret
`,
},
{
sPtr("https://pypi.example.com"),
nil,
nil,
`[distutils]
index-servers =
pypi
[pypi]
repository: https://pypi.example.com
username: guido
password: secret
`,
},
{
nil,
sPtr("jqhacker"),
sPtr("supersecret"),
`[distutils]
index-servers =
pypi
[pypi]
repository: https://pypi.python.org/pypi
username: jqhacker
password: supersecret
`,
},
}
for i, data := range testdata {
v := Params{
Repository: data.repository,
Username: data.username,
Password: data.password,
Distributions: []string{},
}
var b bytes.Buffer
v.WriteConfig(&b)
if b.String() != data.exp {
t.Errorf("Case %d: Expected %s, got %s\n", i, data.exp, b.String())
}
}
}
// TestUpload checks if a distutils upload command can be properly
// formatted.
func TestUpload(t *testing.T) {
testdata := []struct {
distributions []string
exp []string
}{
{
[]string{},
[]string{"python", "setup.py", "sdist", "upload", "-r", "pypi"},
},
{
[]string{"sdist", "bdist_wheel"},
[]string{"python", "setup.py", "sdist", "bdist_wheel", "upload", "-r", "pypi"},
},
}
for i, data := range testdata {
v := Params{Distributions: data.distributions}
c := v.Upload()
if len(c.Args) != len(data.exp) {
t.Errorf("Case %d: Expected %d, got %d", i, len(data.exp), len(c.Args))
}
for i := range c.Args {
if c.Args[i] != data.exp[i] {
t.Errorf("Case %d: Expected %s, got %s", i, strings.Join(data.exp, " "), strings.Join(c.Args, " "))
}
}
}
}
func sPtr(s string) *string {
return &s
}
+65
View File
@@ -0,0 +1,65 @@
package main
import (
"log"
"os/exec"
"github.com/pkg/errors"
)
// Plugin defines the PyPi plugin parameters
type Plugin struct {
Repository string
Username string
Password string
SetupFile string
Distributions []string
SkipBuild bool
}
func (p Plugin) buildCommand() *exec.Cmd {
// Set the default of distributions in here
// as CLI package still has issues with string slice defaults
distributions := []string{"sdist"}
if len(p.Distributions) > 0 {
distributions = p.Distributions
}
args := []string{p.SetupFile}
for i := range distributions {
args = append(args, distributions[i])
}
return exec.Command("python3", args...)
}
func (p Plugin) uploadCommand() *exec.Cmd {
args := []string{}
args = append(args, "upload")
args = append(args, "--repository-url")
args = append(args, p.Repository)
args = append(args, "--username")
args = append(args, p.Username)
args = append(args, "--password")
args = append(args, p.Password)
args = append(args, "dist/*")
return exec.Command("twine", args...)
}
// Exec runs the plugin - doing the necessary setup.py modifications
func (p Plugin) Exec() error {
if !p.SkipBuild {
out, err := p.buildCommand().CombinedOutput()
if err != nil {
return errors.Wrap(err, string(out))
}
log.Printf("Output: %s", out)
}
out, err := p.uploadCommand().CombinedOutput()
if err != nil {
return errors.Wrap(err, string(out))
}
log.Printf("Output: %s", out)
return nil
}
+55
View File
@@ -0,0 +1,55 @@
package main
import (
"os"
"strings"
"testing"
)
func TestPublish(t *testing.T) {
repository := os.Getenv("PLUGIN_REPOSITORY")
username := os.Getenv("PLUGIN_USERNAME")
password := os.Getenv("PLUGIN_PASSWORD")
plugin := Plugin{
Repository: repository,
Username: username,
Password: password,
SetupFile: "testdata/setup.py",
Distributions: strings.Split(os.Getenv("PLUGIN_DISTRIBUTIONS"), " "),
SkipBuild: false,
}
err := plugin.Exec()
if err != nil {
t.Error(err)
}
}
// TestUpload checks if a distutils upload command can be properly
// generated and formatted.
func TestUpload(t *testing.T) {
testdata := []struct {
distributions []string
exp []string
}{
{
[]string{},
[]string{"python3", "testdata/setup.py", "sdist"},
},
{
[]string{"sdist", "bdist_wheel"},
[]string{"python3", "testdata/setup.py", "sdist", "bdist_wheel"},
},
}
for i, data := range testdata {
p := Plugin{Distributions: data.distributions, SetupFile: "testdata/setup.py"}
c := p.buildCommand()
if len(c.Args) != len(data.exp) {
t.Errorf("Case %d: Expected %d, got %d", i, len(data.exp), len(c.Args))
}
for i := range c.Args {
if c.Args[i] != data.exp[i] {
t.Errorf("Case %d: Expected %s, got %s", i, strings.Join(data.exp, " "), strings.Join(c.Args, " "))
}
}
}
}
-3
View File
@@ -1,3 +0,0 @@
*.egg-info/
build/
dist/
+1 -1
View File
@@ -1 +1 @@
A simple test module
Test package for Drone 0.8+ Drone-pypi plugin
+68
View File
@@ -0,0 +1,68 @@
[app:main]
use = egg:pypicloud
pyramid.reload_templates = false
pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
pypi.storage = file
storage.dir = /var/lib/pypicloud/packages
# user: stevearc, pass: gunface
user.stevearc = $5$rounds=80000$yiWi67QBJLDTvbI/$d6qIG/bIoM3hp0lxH8v/vzxg8Qc4CJbxbxiUH4MlnE7
# For beaker
session.encrypt_key = replaceme
session.validate_key = replaceme
session.secure = false
###
# wsgi server configuration
###
[uwsgi]
paste = config:%p
paste-logger = %p
master = true
uid = pypicloud
gid = pypicloud
processes = 20
reload-mercy = 15
worker-reload-mercy = 15
max-requests = 1000
enable-threads = true
http = 0.0.0.0:8080
###
# logging configuration
# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
keys = root, boto
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console
[logger_boto]
level = WARN
qualname = boto
handlers =
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(levelname)s %(asctime)s [%(name)s] %(message)s
View File
+7 -23
View File
@@ -1,28 +1,12 @@
from setuptools import setup
import subprocess
def get_version():
try:
git = subprocess.Popen(
["git", "describe", "--long"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except Exception:
return "0.0.0"
val = git.communicate()[0]
if git.returncode != 0:
return "0.0.0"
l = val.strip().split("-")
return l[0] + "." + l[1]
setup(
name="drone-pypi",
version=get_version(),
description="Module for testing drone-pypi.",
url="http://github.com/drone-plugins/drone-pypi",
packages=["drone_pypi"],
maintainer="Drone Contributors",
maintainer_email="support@drone.io",
name='drone-pypi-testbuild',
version='0.1.0',
description='Testing drone-pypi publishes, no other purpose.',
url='https://github.com/xoxys/drone-pypi',
packages=['testdata/drone_pypi_test'],
maintainer='Robert Kaussow',
maintainer_email="xoxys@rknet.org",
)