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 kind: pipeline
environment: name: testing
- GO15VENDOREXPERIMENT=1
- GOOS=linux platform:
- GOARCH=amd64 os: linux
- CGO_ENABLED=0 arch: amd64
- DRONE_PYPI_PATH=testdata
- DRONE_PYPI_REPOSITORY=http://localhost:8000 steps:
- DRONE_PYPI_DISTRIBUTIONS=sdist - name: vet
pull: always
image: golang:1.11
commands: commands:
- apt-get update && apt-get install -y python-setuptools - go vet ./...
- go get environment:
- go build GO111MODULE: on
- go test -cover
compose: - name: test
simplepypi: pull: always
image: msteinert/simplepypi image: golang:1.11-alpine
pull: true 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: services:
docker: - name: pypiserver
username: drone pull: always
password: $$DOCKER_PASS image: pypiserver/pypiserver
email: $$DOCKER_EMAIL entrypoint:
repo: plugins/drone-pypi - pypi-server
when: - -P
branch: master - .
- -a
- .
- -p
- 8080
- /data/packages
plugin: trigger:
name: Pypi branch:
desc: Publish a package to the Python package index. - master
type: publish
image: plugins/drone-pypi ---
labels: kind: pipeline
- publish name: linux-amd64
- python
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 *.test
*.prof *.prof
release/
vendor/
coverage.out
drone-pypi 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. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. 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 # drone-pypi
[![Build Status](http://beta.drone.io/api/badges/drone-plugins/drone-pypi/status.svg)](http://beta.drone.io/drone-plugins/drone-pypi) [![Build Status](http://cloud.drone.io/api/badges/drone-plugins/drone-pypi/status.svg)](http://cloud.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') [![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 ```Shell
./drone-pypi <<EOF export GOOS=linux
{ export GOARCH=amd64
"workspace": { export CGO_ENABLED=0
"path": "/drone/my-module-py" export GO111MODULE=on
}
"vargs": { go build -v -a -tags netgo -o release/linux/amd64/drone-pypi
"username": "guido",
"password": "secret"
}
}
EOF
``` ```
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 ## Docker
Build the Docker container using the `netgo` build tag to eliminate Build the Docker image with the following commands:
the CGO dependency:
```sh ```Shell
CGO_ENABLED=0 go build -a -tags netgo docker build \
docker build --rm=true -t plugins/drone-pypi . --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 package main
import ( import (
"bufio"
"fmt" "fmt"
"io"
"log"
"os" "os"
"os/exec"
"path"
"strings"
"github.com/drone/drone-go/drone" "github.com/urfave/cli"
"github.com/drone/drone-go/plugin" _ "github.com/joho/godotenv/autoload"
) )
// Params desribes how to upload a Python module to PyPI. var build = "0" // build number set at compile-time
type Params struct {
Distributions []string `json:"distributions"`
Password *string `json:"password,omitempty"`
Repository *string `json:"repository,omitempty"`
Username *string `json:"username,omitempty"`
}
func main() { func main() {
w := drone.Workspace{} app := cli.NewApp()
v := Params{} app.Name = "pypi plugin"
plugin.Param("workspace", &w) app.Usage = "pypi publish plugin"
plugin.Param("vargs", &v) app.Action = run
plugin.MustParse() app.Version = fmt.Sprintf("0.0.%s", build)
app.Flags = []cli.Flag{
err := v.Deploy(&w) cli.StringFlag{
if err != nil { Name: "repository",
log.Fatal(err) 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 run(c *cli.Context) {
func (v *Params) Deploy(w *drone.Workspace) error { plugin := Plugin{
err := v.CreateConfig() Repository: c.String("repository"),
if err != nil { Username: c.String("username"),
return err 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 if err := plugin.Exec(); err != nil {
// the current user. fmt.Println(err)
func (v *Params) CreateConfig() error { os.Exit(1)
f, err := os.Create(path.Join(os.Getenv("HOME"), ".pypirc"))
if err != nil {
return err
} }
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 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( setup(
name="drone-pypi", name='drone-pypi-testbuild',
version=get_version(), version='0.1.0',
description="Module for testing drone-pypi.", description='Testing drone-pypi publishes, no other purpose.',
url="http://github.com/drone-plugins/drone-pypi", url='https://github.com/xoxys/drone-pypi',
packages=["drone_pypi"], packages=['testdata/drone_pypi_test'],
maintainer="Drone Contributors", maintainer='Robert Kaussow',
maintainer_email="support@drone.io", maintainer_email="xoxys@rknet.org",
) )