You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2022/09/02 18:46:43 UTC

[libcloud] branch pip_audit_gha_check updated (f875502c4 -> ca81f08fa)

This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a change to branch pip_audit_gha_check
in repository https://gitbox.apache.org/repos/asf/libcloud.git


    from f875502c4 Add new GHA step which runs pip audit check.
     new c1645fa1b Squashed '.github/actions/gh-action-pip-audit/' content from commit cce88443a
     new 2cbd7a45e Merge commit 'c1645fa1b1e016779b826f467deb740aabe90eb8' as '.github/actions/gh-action-pip-audit'
     new ca81f08fa Add github action to the repo as subtree since ASF policy doesn't allow using external actions.

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../gh-action-pip-audit/.github/workflows/ci.yml   |  18 +
 .../.github/workflows/selftest.yml                 |  90 +++++
 .github/actions/gh-action-pip-audit/.gitignore     |   1 +
 .../actions/gh-action-pip-audit/LICENSE            |  25 --
 .github/actions/gh-action-pip-audit/Makefile       |  17 +
 .github/actions/gh-action-pip-audit/README.md      | 365 +++++++++++++++++++++
 .github/actions/gh-action-pip-audit/action.py      | 169 ++++++++++
 .github/actions/gh-action-pip-audit/action.yml     |  87 +++++
 .../gh-action-pip-audit/dev-requirements.txt       |   3 +
 .../actions/gh-action-pip-audit/requirements.txt   |   1 +
 .../actions/gh-action-pip-audit/setup/setup.bash   |  28 ++
 .../actions/gh-action-pip-audit/setup/venv.bash    |  24 ++
 .../test/pyproject/pyproject.toml                  |   6 +
 .../gh-action-pip-audit/test/vulnerable.txt        |   1 +
 .github/workflows/main.yml                         |   2 +-
 15 files changed, 811 insertions(+), 26 deletions(-)
 create mode 100644 .github/actions/gh-action-pip-audit/.github/workflows/ci.yml
 create mode 100644 .github/actions/gh-action-pip-audit/.github/workflows/selftest.yml
 create mode 100644 .github/actions/gh-action-pip-audit/.gitignore
 copy LICENSE => .github/actions/gh-action-pip-audit/LICENSE (89%)
 create mode 100644 .github/actions/gh-action-pip-audit/Makefile
 create mode 100644 .github/actions/gh-action-pip-audit/README.md
 create mode 100755 .github/actions/gh-action-pip-audit/action.py
 create mode 100644 .github/actions/gh-action-pip-audit/action.yml
 create mode 100644 .github/actions/gh-action-pip-audit/dev-requirements.txt
 create mode 100644 .github/actions/gh-action-pip-audit/requirements.txt
 create mode 100644 .github/actions/gh-action-pip-audit/setup/setup.bash
 create mode 100644 .github/actions/gh-action-pip-audit/setup/venv.bash
 create mode 100644 .github/actions/gh-action-pip-audit/test/pyproject/pyproject.toml
 create mode 100644 .github/actions/gh-action-pip-audit/test/vulnerable.txt


[libcloud] 02/03: Merge commit 'c1645fa1b1e016779b826f467deb740aabe90eb8' as '.github/actions/gh-action-pip-audit'

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch pip_audit_gha_check
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit 2cbd7a45e171d0d68e9795c15598c7a74a340a34
Merge: f875502c4 c1645fa1b
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Sep 2 20:46:14 2022 +0200

    Merge commit 'c1645fa1b1e016779b826f467deb740aabe90eb8' as '.github/actions/gh-action-pip-audit'

 .../gh-action-pip-audit/.github/workflows/ci.yml   |  18 +
 .../.github/workflows/selftest.yml                 |  90 +++++
 .github/actions/gh-action-pip-audit/.gitignore     |   1 +
 .github/actions/gh-action-pip-audit/LICENSE        | 177 ++++++++++
 .github/actions/gh-action-pip-audit/Makefile       |  17 +
 .github/actions/gh-action-pip-audit/README.md      | 365 +++++++++++++++++++++
 .github/actions/gh-action-pip-audit/action.py      | 169 ++++++++++
 .github/actions/gh-action-pip-audit/action.yml     |  87 +++++
 .../gh-action-pip-audit/dev-requirements.txt       |   3 +
 .../actions/gh-action-pip-audit/requirements.txt   |   1 +
 .../actions/gh-action-pip-audit/setup/setup.bash   |  28 ++
 .../actions/gh-action-pip-audit/setup/venv.bash    |  24 ++
 .../test/pyproject/pyproject.toml                  |   6 +
 .../gh-action-pip-audit/test/vulnerable.txt        |   1 +
 14 files changed, 987 insertions(+)

diff --cc .github/actions/gh-action-pip-audit/.github/workflows/ci.yml
index 000000000,b05f79543..b05f79543
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/.github/workflows/ci.yml
+++ b/.github/actions/gh-action-pip-audit/.github/workflows/ci.yml
diff --cc .github/actions/gh-action-pip-audit/.github/workflows/selftest.yml
index 000000000,864028402..864028402
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/.github/workflows/selftest.yml
+++ b/.github/actions/gh-action-pip-audit/.github/workflows/selftest.yml
diff --cc .github/actions/gh-action-pip-audit/.gitignore
index 000000000,bdaab25d5..bdaab25d5
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/.gitignore
+++ b/.github/actions/gh-action-pip-audit/.gitignore
diff --cc .github/actions/gh-action-pip-audit/LICENSE
index 000000000,f433b1a53..f433b1a53
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/LICENSE
+++ b/.github/actions/gh-action-pip-audit/LICENSE
diff --cc .github/actions/gh-action-pip-audit/Makefile
index 000000000,77fd0ac52..77fd0ac52
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/Makefile
+++ b/.github/actions/gh-action-pip-audit/Makefile
diff --cc .github/actions/gh-action-pip-audit/README.md
index 000000000,825721c95..825721c95
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/README.md
+++ b/.github/actions/gh-action-pip-audit/README.md
diff --cc .github/actions/gh-action-pip-audit/action.py
index 000000000,aac0643f1..aac0643f1
mode 000000,100755..100755
--- a/.github/actions/gh-action-pip-audit/action.py
+++ b/.github/actions/gh-action-pip-audit/action.py
diff --cc .github/actions/gh-action-pip-audit/action.yml
index 000000000,3574e61fa..3574e61fa
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/action.yml
+++ b/.github/actions/gh-action-pip-audit/action.yml
diff --cc .github/actions/gh-action-pip-audit/dev-requirements.txt
index 000000000,f086aa46b..f086aa46b
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/dev-requirements.txt
+++ b/.github/actions/gh-action-pip-audit/dev-requirements.txt
diff --cc .github/actions/gh-action-pip-audit/requirements.txt
index 000000000,ca00871fd..ca00871fd
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/requirements.txt
+++ b/.github/actions/gh-action-pip-audit/requirements.txt
diff --cc .github/actions/gh-action-pip-audit/setup/setup.bash
index 000000000,e4d8a8239..e4d8a8239
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/setup/setup.bash
+++ b/.github/actions/gh-action-pip-audit/setup/setup.bash
diff --cc .github/actions/gh-action-pip-audit/setup/venv.bash
index 000000000,3e6064538..3e6064538
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/setup/venv.bash
+++ b/.github/actions/gh-action-pip-audit/setup/venv.bash
diff --cc .github/actions/gh-action-pip-audit/test/pyproject/pyproject.toml
index 000000000,12ce5e737..12ce5e737
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/test/pyproject/pyproject.toml
+++ b/.github/actions/gh-action-pip-audit/test/pyproject/pyproject.toml
diff --cc .github/actions/gh-action-pip-audit/test/vulnerable.txt
index 000000000,6c05a614d..6c05a614d
mode 000000,100644..100644
--- a/.github/actions/gh-action-pip-audit/test/vulnerable.txt
+++ b/.github/actions/gh-action-pip-audit/test/vulnerable.txt


[libcloud] 01/03: Squashed '.github/actions/gh-action-pip-audit/' content from commit cce88443a

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch pip_audit_gha_check
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit c1645fa1b1e016779b826f467deb740aabe90eb8
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Sep 2 20:46:14 2022 +0200

    Squashed '.github/actions/gh-action-pip-audit/' content from commit cce88443a
    
    git-subtree-dir: .github/actions/gh-action-pip-audit
    git-subtree-split: cce88443a7a495d91316565f5cc077f815a8f1c7
---
 .github/workflows/ci.yml       |  18 ++
 .github/workflows/selftest.yml |  90 ++++++++++
 .gitignore                     |   1 +
 LICENSE                        | 177 ++++++++++++++++++++
 Makefile                       |  17 ++
 README.md                      | 365 +++++++++++++++++++++++++++++++++++++++++
 action.py                      | 169 +++++++++++++++++++
 action.yml                     |  87 ++++++++++
 dev-requirements.txt           |   3 +
 requirements.txt               |   1 +
 setup/setup.bash               |  28 ++++
 setup/venv.bash                |  24 +++
 test/pyproject/pyproject.toml  |   6 +
 test/vulnerable.txt            |   1 +
 14 files changed, 987 insertions(+)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 000000000..b05f79543
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,18 @@
+name: CI
+
+on:
+  push:
+    branches:
+      - main
+  pull_request:
+
+jobs:
+  lint:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: "3.7"
+      - name: lint
+        run: make lint
diff --git a/.github/workflows/selftest.yml b/.github/workflows/selftest.yml
new file mode 100644
index 000000000..864028402
--- /dev/null
+++ b/.github/workflows/selftest.yml
@@ -0,0 +1,90 @@
+name: Self-test
+
+on:
+  push:
+    branches:
+      - main
+  pull_request:
+  workflow_dispatch:
+
+jobs:
+  selftest-requirements:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: ./
+        id: pip-audit
+        with:
+          inputs: ./test/vulnerable.txt
+          no-deps: true
+          # NOTE: We intentionally allow failure here, since the self-test
+          # explicitly uses a vulnerable requirements file.
+          internal-be-careful-allow-failure: true
+      - name: assert expected output
+        env:
+          PIP_AUDIT_OUTPUT: "${{ steps.pip-audit.outputs.internal-be-careful-output }}"
+        run: |
+          grep -E 'pyyaml\s+\|\s+5.1' <<< $(base64 -d <<< "${PIP_AUDIT_OUTPUT}")
+
+  selftest-environment:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: make the environment vulnerable
+        run: |
+          python -m pip install --no-deps --requirement ./test/vulnerable.txt
+      - uses: ./
+        id: pip-audit
+        with:
+          # NOTE: We intentionally allow failure here, since the self-test
+          # explicitly uses a vulnerable requirements file.
+          internal-be-careful-allow-failure: true
+      - name: assert expected output
+        env:
+          PIP_AUDIT_OUTPUT: "${{ steps.pip-audit.outputs.internal-be-careful-output }}"
+        run: |
+          grep -E 'pyyaml\s+\|\s+5.1' <<< $(base64 -d <<< "${PIP_AUDIT_OUTPUT}")
+
+  selftest-virtualenv:
+    strategy:
+      matrix:
+        local: [true, false]
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: make a virtual environment vulnerable
+        run: |
+          python -m venv env
+          ./env/bin/python -m pip install --upgrade pip wheel
+          ./env/bin/python -m pip install --no-deps --requirement ./test/vulnerable.txt
+      - uses: ./
+        id: pip-audit
+        with:
+          virtual-environment: env/
+          local: ${{ matrix.local }}
+          # NOTE: We intentionally allow failure here, since the self-test
+          # explicitly uses a vulnerable requirements file.
+          internal-be-careful-allow-failure: true
+      - name: assert expected output
+        env:
+          PIP_AUDIT_OUTPUT: "${{ steps.pip-audit.outputs.internal-be-careful-output }}"
+        run: |
+          grep -E 'pyyaml\s+\|\s+5.1' <<< $(base64 -d <<< "${PIP_AUDIT_OUTPUT}")
+
+  selftest-pyproject:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: ./
+        id: pip-audit
+        with:
+          # should attempt to discover test/pyproject/pyproject.toml
+          inputs: test/pyproject/
+          # NOTE: We intentionally allow failure here, since the self-test
+          # explicitly uses a vulnerable requirements file.
+          internal-be-careful-allow-failure: true
+      - name: assert expected output
+        env:
+          PIP_AUDIT_OUTPUT: "${{ steps.pip-audit.outputs.internal-be-careful-output }}"
+        run: |
+          grep -E 'pyyaml\s+\|\s+5.1' <<< $(base64 -d <<< "${PIP_AUDIT_OUTPUT}")
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..bdaab25d5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+env/
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 000000000..f433b1a53
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,177 @@
+
+                                 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
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..77fd0ac52
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,17 @@
+.PHONY: all
+all:
+	@echo "Run my targets individually!"
+
+env/pyvenv.cfg: dev-requirements.txt
+	python -m venv env
+	./env/bin/python -m pip install --upgrade pip
+	./env/bin/python -m pip install --requirement dev-requirements.txt
+
+.PHONY: dev
+dev: env/pyvenv.cfg
+
+.PHONY: lint
+lint: env/pyvenv.cfg action.py
+	./env/bin/python -m black action.py
+	./env/bin/python -m isort action.py
+	./env/bin/python -m flake8 --max-line-length 100 action.py
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..825721c95
--- /dev/null
+++ b/README.md
@@ -0,0 +1,365 @@
+gh-action-pip-audit
+===================
+
+[![CI](https://github.com/trailofbits/gh-action-pip-audit/actions/workflows/ci.yml/badge.svg)](https://github.com/trailofbits/gh-action-pip-audit/actions/workflows/ci.yml)
+[![Self-test](https://github.com/trailofbits/gh-action-pip-audit/actions/workflows/selftest.yml/badge.svg)](https://github.com/trailofbits/gh-action-pip-audit/actions/workflows/selftest.yml)
+
+A GitHub Action that uses [`pip-audit`](https://github.com/trailofbits/pip-audit)
+to scan Python dependencies for known vulnerabilities.
+
+## Index
+
+* [Usage](#usage)
+* [Configuration](#configuration)
+  * [⚠️ Internal options ⚠️](#internal-options)
+* [Troubleshooting](#troubleshooting)
+* [Licensing](#licensing)
+* [Code of Conduct](#code-of-conduct)
+
+## Usage
+
+Simply add `trailofbits/gh-action-pip-audit` to one of your workflows:
+
+```yaml
+jobs:
+  selftest:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: install
+        run: python -m pip install .
+      - uses: trailofbits/gh-action-pip-audit@v1.0.0
+```
+
+Or, with a virtual environment:
+
+```yaml
+jobs:
+  selftest:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: install
+        run: |
+          python -m venv env/
+          source env/bin/activate
+          python -m pip install .
+      - uses: trailofbits/gh-action-pip-audit@v1.0.0
+        with:
+          virtual-environment: env/
+```
+
+By default, `pip-audit` will run in "`pip list` source" mode, meaning that it'll
+attempt to collect dependencies from the local environment. See
+the [configuration](#configuration) documentation below for more input
+and behavioral options.
+
+## Configuration
+
+`gh-action-pip-audit` takes a variety of configuration inputs, all of which are
+optional.
+
+### `inputs`
+
+**Default**: Empty, indicating "`pip list` source" mode
+
+The `inputs` setting controls what sources `pip-audit` runs on.
+
+To audit one or more requirements-style inputs:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    inputs: requirements.txt dev-requirements.txt
+```
+
+To audit a project that uses `pyproject.toml` for its dependencies:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    # NOTE: this can be `.`, for the current directory
+    inputs: path/to/project/
+```
+
+### `virtual-environment`
+
+**Default**: Empty, indicating no virtual environment
+
+The `virtual-environment` setting controls the
+[virtual environment](https://docs.python.org/3/tutorial/venv.html) that this
+action loads to, if specified. The value is the top-level directory for the
+virtual environment, which is conventionally named `env` or `venv`.
+
+Depending on your CI and project configuration, you may or may not need this
+setting. Specifically, you only need it if you satisfy *all* of the following
+conditions:
+
+1. You are auditing an *environment* (**not** a requirements file or other
+   project metadata)
+2. Your environment is not already "active", i.e. `python -m pip` points to a
+   different `pip` than the one that your environment uses
+
+Example: use the virtual environment specified at `env/`, relative to the
+current directory:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    virtual-environment: env/
+    # Note the absence of `input:`, since we're auditing the environment.
+```
+
+### `local`
+
+**Default**: `false`
+
+The `local` setting corresponds to `pip-audit`'s `--local` flag, which controls
+whether non-local dependencies are included when auditing in "`pip list` source"
+mode.
+
+By default all dependencies are included; with `local: true`, only dependencies
+installed directly into the current environment are included.
+
+Example:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    local: true
+```
+
+### `vulnerability-service`
+
+**Default**: `PyPI`
+
+**Options**: `PyPI`, `OSV` (case insensitive)
+
+The `vulnerability-service` setting controls which vulnerability service is used for the audit.
+It's directly equivalent to `pip-audit --vulnerability-service=...`.
+
+To audit with OSV instead of PyPI:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    vulnerability-service: osv
+```
+
+### `require-hashes`
+
+**Default**: `false`
+
+The `require-hashes` setting controls whether strict hash checking is enabled.
+It's directly equivalent to `pip-audit --require-hashes ...`.
+
+Example:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    # NOTE: only works with requirements-style inputs
+    inputs: requirements.txt
+    require-hashes: true
+```
+
+### `no-deps`
+
+**Default**: `false`
+
+The `no-deps` setting controls whether dependency resolution is performed.
+It's directly equivalent to `pip-audit --no-deps ...`.
+
+Example:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    # NOTE: only works with requirements-style inputs
+    inputs: requirements.txt
+    no-deps: true
+```
+
+### `summary`
+
+**Default**: `true`
+
+The `summary` setting controls whether a GitHub
+[job summary](https://github.blog/2022-05-09-supercharging-github-actions-with-job-summaries/)
+is rendered at the end of the action.
+
+Example:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    summary: false
+  ```
+
+### `index-url`
+
+**Default**: Empty, indicating [PyPI](https://pypi.org)
+
+The `index-url` setting specifies a base URL for an alternative PEP 503-compatible
+package index.
+
+**This is probably not want you want.** If your goal is to add *complementary*
+indices to search (such as a corporate index with private packages), see
+[`extra-index-urls`](#extra-index-urls).
+
+Example:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    index-url: https://example.corporate.local/simple
+```
+
+### `extra-index-urls`
+
+**Default**: Empty (no extra indexes are searched by default)
+
+The `extra-index-urls` setting specifies one or more *extra* PEP 503-compatible packages
+indexes to search when resolving dependencies. Each URL is whitespace-separated.
+
+Example:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    extra-index-urls: |
+      https://example.corporate.local/simple
+      https://prod.corporate.local/simple
+```
+
+### `ignore-vulns`
+
+**Default**: Empty (no vulnerabilities are ignored)
+
+The `ignore-vulns` setting specifies one or more vulnerability IDs to
+ignore (i.e., exclude from the results) if present. Each ID is whitespace-separated.
+
+Example
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    ignore-vulns: |
+      GHSA-XXXX-YYYYYY
+      PYSEC-AAAA-BBBBB
+```
+
+### Internal options
+<details>
+  <summary>⚠️ Internal options ⚠️</summary>
+
+  Everything below is considered "internal," which means that it
+  isn't part of the stable public settings and may be removed or changed at
+  any point. **You probably do not need these settings.**
+
+  All internal options are prefixed with `internal-be-careful-`.
+
+  #### `internal-be-careful-allow-failure`
+
+  **Default**: `false`
+
+  The `internal-be-careful-allow-failure` setting allows the job to pass, even
+  if the underlying `pip-audit` run fails (e.g. due to vulnerabilities detected).
+
+  Be very careful with this setting! Using it unwittingly will prevent the action
+  from failing your CI when `pip-audit` fails, which is probably not what you want.
+
+  Example:
+
+  ```yaml
+  - uses: trailofbits/gh-action-pip-audit@v1.0.0
+    with:
+      internal-be-careful-allow-failure: true
+  ```
+
+  #### `internal-be-careful-debug`
+
+  **Default**: `false`
+
+  The `internal-be-careful-debug` setting enables additional debug logs,
+  both within `pip-audit` itself and the action's harness code. You can
+  use it to debug troublesome configurations.
+
+  Be mindful that `pip-audit`'s own debug logs contain HTTP requests,
+  which may or may not be sensitive in your use case.
+
+  Example:
+
+  ```yaml
+  - uses: trailofbits/gh-action-pip-audit@v1.0.0
+    with:
+      internal-be-careful-debug: true
+  ```
+
+</details>
+
+## Troubleshooting
+
+This section is still a work in progress. Please help us improve it!
+
+### The action takes longer than I expect!
+
+If you're auditing a requirements file, consider setting `no-deps: true` or
+`require-hashes: true`:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    inputs: requirements.txt
+    require-hashes: true
+```
+
+or:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    inputs: requirements.txt
+    no-deps: true
+```
+
+See the
+["`pip-audit` takes longer than I expect!"](https://github.com/trailofbits/pip-audit#pip-audit-takes-longer-than-i-expect)
+troubleshooting for more details.
+
+### The action shows dependencies that aren't in my environment!
+
+In the default ("`pip list` source") configuration, `pip-audit` collects all
+dependencies that are visible in the current environment.
+
+Depending on the project or CI's configuration, this can include packages installed
+by the host system itself, or other Python projects that happen to be installed.
+
+To minimize external dependencies, you can opt into a virtual environment:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    # must be populated earlier in the CI
+    virtual-environment: env/
+```
+
+and, more aggressively, specify that only dependencies marked as "local"
+in the virtual environment should be included:
+
+```yaml
+- uses: trailofbits/gh-action-pip-audit@v1.0.0
+  with:
+    # must be populated earlier in the CI
+    virtual-environment: env/
+    local: true
+```
+
+## Licensing
+
+`gh-action-pip-audit` is licensed under the Apache 2.0 License.
+
+## Code of Conduct
+
+Everyone interacting with this project is expected to follow the
+[PSF Code of Conduct](https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md).
diff --git a/action.py b/action.py
new file mode 100755
index 000000000..aac0643f1
--- /dev/null
+++ b/action.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python3
+
+# action.py: run pip-audit
+#
+# most state is passed in as environment variables; the only argument
+# is a whitespace-separated list of inputs
+
+import os
+import subprocess
+import sys
+from base64 import b64encode
+from pathlib import Path
+
+_OUTPUTS = [sys.stderr]
+_SUMMARY = Path(os.getenv("GITHUB_STEP_SUMMARY")).open("a")
+_RENDER_SUMMARY = os.getenv("GHA_PIP_AUDIT_SUMMARY", "true") == "true"
+_DEBUG = os.getenv("GHA_PIP_AUDIT_INTERNAL_BE_CAREFUL_DEBUG", "false") != "false"
+
+if _RENDER_SUMMARY:
+    _OUTPUTS.append(_SUMMARY)
+
+
+def _summary(msg):
+    if _RENDER_SUMMARY:
+        print(msg, file=_SUMMARY)
+
+
+def _debug(msg):
+    if _DEBUG:
+        print(f"\033[93mDEBUG: {msg}\033[0m", file=sys.stderr)
+
+
+def _log(msg):
+    for output in _OUTPUTS:
+        print(msg, file=output)
+
+
+def _pip_audit(*args):
+    return ["python", "-m", "pip_audit", *args]
+
+
+def _fatal_help(msg):
+    print(f"::error::❌ {msg}")
+    sys.exit(1)
+
+
+inputs = [Path(p).resolve() for p in sys.argv[1].split()]
+summary = Path(os.getenv("GITHUB_STEP_SUMMARY")).open("a")
+
+# The arguments we pass into `pip-audit` get built up in this list.
+pip_audit_args = [
+    # The spinner is useless in the CI.
+    "--progress-spinner=off",
+    # We intend to emit a Markdown-formatted table.
+    "--format=markdown",
+    # `pip cache dir` doesn't work in this container for some reason, and I
+    # haven't debugged it yet.
+    "--cache-dir=/tmp/pip-audit-cache",
+    # Include full descriptions in the output.
+    "--desc",
+    # Write the output to this logfile, which we'll turn into the step summary (if configured).
+    "--output=/tmp/pip-audit-output.txt",
+]
+
+if _DEBUG:
+    pip_audit_args.append("--verbose")
+
+if os.getenv("GHA_PIP_AUDIT_NO_DEPS", "false") != "false":
+    pip_audit_args.append("--no-deps")
+
+if os.getenv("GHA_PIP_AUDIT_REQUIRE_HASHES", "false") != "false":
+    pip_audit_args.append("--require-hashes")
+
+if os.getenv("GHA_PIP_AUDIT_LOCAL", "false") != "false":
+    pip_audit_args.append("--local")
+
+index_url = os.getenv("GHA_PIP_AUDIT_INDEX_URL")
+if index_url != "":
+    pip_audit_args.extend(["--index-url", index_url])
+
+
+extra_index_urls = os.getenv("GHA_PIP_AUDIT_EXTRA_INDEX_URLS", "").split()
+for url in extra_index_urls:
+    pip_audit_args.extend(["--extra-index-url", url])
+
+
+ignored_vuln_ids = os.getenv("GHA_PIP_AUDIT_IGNORE_VULNS", "").split()
+for vuln_id in ignored_vuln_ids:
+    pip_audit_args.extend(["--ignore-vuln", vuln_id])
+
+pip_audit_args.extend(
+    [
+        "--vulnerability-service",
+        os.getenv("GHA_PIP_AUDIT_VULNERABILITY_SERVICE", "pypi").lower(),
+    ]
+)
+
+# If inputs is empty, we let `pip-audit` run in "`pip list` source" mode by not
+# adding any explicit input argument(s).
+# Otherwise, we handle either exactly one project path (a directory)
+# or one or more requirements-style inputs (all files).
+for input_ in inputs:
+    # Forbid things that look like flags. This isn't a security boundary; just
+    # a way to prevent (less motivated) users from breaking the action on themselves.
+    if str(input_).startswith("-"):
+        _fatal_help(f"input {input_} looks like a flag")
+
+    if input_.is_dir():
+        if len(inputs) != 1:
+            _fatal_help("pip-audit only supports one project directory at a time")
+        pip_audit_args.append(input_)
+    else:
+        if not input_.is_file():
+            _fatal_help(f"input {input_} does not look like a file")
+        pip_audit_args.extend(["--requirement", input_])
+
+_debug(f"running: pip-audit {[str(a) for a in pip_audit_args]}")
+
+status = subprocess.run(
+    _pip_audit(*pip_audit_args),
+    text=True,
+    stdout=subprocess.PIPE,
+    stderr=subprocess.STDOUT,
+    env={**os.environ, "PIP_NO_CACHE_DIR": "1"},
+)
+
+_debug(status.stdout)
+
+if status.returncode == 0:
+    _log("🎉 pip-audit exited successfully")
+else:
+    _log("❌ pip-audit found one or more problems")
+
+    with open("/tmp/pip-audit-output.txt", "r") as io:
+        output = io.read()
+
+        # This is really nasty: our output contains multiple lines,
+        # so we can't naively stuff it into an output (since this is all done
+        # in-channel as a special command on stdout).
+        print(f"::set-output name=output::{b64encode(output.encode()).decode()}")
+
+        _log(output)
+
+
+_summary(
+    """
+<details>
+<summary>
+    Raw `pip-audit` output
+</summary>
+
+```
+    """
+)
+_log(status.stdout)
+_summary(
+    """
+```
+</details>
+    """
+)
+
+# Normally, we exit with the same code as `pip-audit`, but the user can
+# explicitly configure the CI to always pass.
+# This is primarily useful for our own self-test workflows.
+if os.getenv("GHA_PIP_AUDIT_INTERNAL_BE_CAREFUL_ALLOW_FAILURE", "false") != "false":
+    sys.exit(0)
+else:
+    sys.exit(status.returncode)
diff --git a/action.yml b/action.yml
new file mode 100644
index 000000000..3574e61fa
--- /dev/null
+++ b/action.yml
@@ -0,0 +1,87 @@
+name: "gh-action-pip-audit"
+author: "William Woodruff <wi...@trailofbits.com>"
+description: "Use pip-audit to scan Python dependencies for known vulnerabilities"
+inputs:
+  summary:
+    description: "render a Markdown summary of the audit (default true)"
+    required: false
+    default: true
+  no-deps:
+    description: "don't do any dependency resolution (requires fully pinned requirements) (default false)"
+    required: false
+    default: false
+  require-hashes:
+    description: "enforce hashes (requirements-style inputs only) (default false)"
+    required: false
+    default: false
+  vulnerability-service:
+    description: "the vulnerability service to use (PyPI or OSV, defaults to PyPI)"
+    required: false
+    default: "PyPI"
+  inputs:
+    description: "the inputs to audit, whitespace separated (defaults to current path)"
+    required: false
+    default: ""
+  virtual-environment:
+    description: "the virtual environment to audit within (default none)"
+    required: false
+    default: ""
+  local:
+    description: "for environmental audits, consider only packages marked local (default false)"
+    required: false
+    default: false
+  index-url:
+    description: "the base URL for the PEP 503-compatible package index to use"
+    required: false
+    default: ""
+  extra-index-urls:
+    description: "extra PEP 503-compatible indexes to use, whitespace separated"
+    required: false
+    default: ""
+  ignore-vulns:
+    description: "vulnerabilities to explicitly exclude, if present (whitespace separated)"
+    required: false
+    default: ""
+  internal-be-careful-allow-failure:
+    description: "don't fail the job if the audit fails (default false)"
+    required: false
+    default: false
+  internal-be-careful-debug:
+    description: "run with debug logs (default false)"
+    required: false
+    default: false
+outputs:
+  internal-be-careful-output:
+    description: "the column-formatted output from pip-audit, wrapped as base64"
+    value: "${{ steps.pip-audit.outputs.output }}"
+runs:
+  using: "composite"
+  steps:
+    - name: Set up pip-audit
+      run: |
+        # NOTE: Sourced, not executed as a script.
+        source "${{ github.action_path }}/setup/setup.bash"
+      env:
+        GHA_PIP_AUDIT_VIRTUAL_ENVIRONMENT: "${{ inputs.virtual-environment }}"
+      shell: bash
+
+    - name: Run pip-audit
+      id: pip-audit
+      run: |
+        # NOTE: Sourced, not executed as a script.
+        source "${{ github.action_path }}/setup/venv.bash"
+
+        ${{ github.action_path }}/action.py "${{ inputs.inputs }}"
+      env:
+        GHA_PIP_AUDIT_SUMMARY: "${{ inputs.summary }}"
+        GHA_PIP_AUDIT_NO_DEPS: "${{ inputs.no-deps }}"
+        GHA_PIP_AUDIT_REQUIRE_HASHES: "${{ inputs.require-hashes }}"
+        GHA_PIP_AUDIT_VULNERABILITY_SERVICE: "${{ inputs.vulnerability-service }}"
+        GHA_PIP_AUDIT_VIRTUAL_ENVIRONMENT: "${{ inputs.virtual-environment }}"
+        GHA_PIP_AUDIT_LOCAL: "${{ inputs.local }}"
+        GHA_PIP_AUDIT_INDEX_URL: "${{ inputs.index-url }}"
+        GHA_PIP_AUDIT_EXTRA_INDEX_URLS: "${{ inputs.extra-index-urls }}"
+        GHA_PIP_AUDIT_IGNORE_VULNS: "${{ inputs.ignore-vulns }}"
+        GHA_PIP_AUDIT_INTERNAL_BE_CAREFUL_ALLOW_FAILURE: "${{ inputs.internal-be-careful-allow-failure }}"
+        GHA_PIP_AUDIT_INTERNAL_BE_CAREFUL_DEBUG: "${{ inputs.internal-be-careful-debug }}"
+      shell: bash
diff --git a/dev-requirements.txt b/dev-requirements.txt
new file mode 100644
index 000000000..f086aa46b
--- /dev/null
+++ b/dev-requirements.txt
@@ -0,0 +1,3 @@
+flake8
+isort
+black
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 000000000..ca00871fd
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+pip-audit==2.4.3
diff --git a/setup/setup.bash b/setup/setup.bash
new file mode 100644
index 000000000..e4d8a8239
--- /dev/null
+++ b/setup/setup.bash
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+
+set -eo pipefail
+
+die() {
+  echo "::error::${1}"
+  exit 1
+}
+
+# NOTE: This file is meant to be sourced, not executed as a script.
+if [[ "${0}" == "${BASH_SOURCE[0]}" ]]; then
+  die "Internal error: setup harness was executed instead of being sourced?"
+fi
+
+# Load the virtual environment, if there is one.
+source "${GITHUB_ACTION_PATH}/setup/venv.bash"
+
+# Check the Python version, making sure it's new enough (3.7+)
+# The installation step immediately below will technically catch this,
+# but doing it explicitly gives us the opportunity to produce a better
+# error message.
+vers=$(python -V | cut -d ' ' -f2)
+maj_vers=$(cut -d '.' -f1 <<< "${vers}")
+min_vers=$(cut -d '.' -f2 <<< "${vers}")
+
+[[ "${maj_vers}" == "3" && "${min_vers}" -ge 7 ]] || die "Bad Python version: ${vers}"
+
+python -m pip install --requirement "${GITHUB_ACTION_PATH}/requirements.txt"
diff --git a/setup/venv.bash b/setup/venv.bash
new file mode 100644
index 000000000..3e6064538
--- /dev/null
+++ b/setup/venv.bash
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+set -eo pipefail
+
+die() {
+  echo "::error::${1}"
+  exit 1
+}
+
+# NOTE: This file is meant to be sourced, not executed as a script.
+if [[ "${0}" == "${BASH_SOURCE[0]}" ]]; then
+  die "Internal error: setup harness was executed instead of being sourced?"
+fi
+
+# If the user has explicitly specified a virtual environment, then we install
+# `pip-audit` into it rather than into whatever environment the default
+# `python -m pip install ...` invocation might happen to choose.
+if [[ -n "${GHA_PIP_AUDIT_VIRTUAL_ENVIRONMENT}" ]] ; then
+  if [[ -d "${GHA_PIP_AUDIT_VIRTUAL_ENVIRONMENT}" ]]; then
+    source "${GHA_PIP_AUDIT_VIRTUAL_ENVIRONMENT}/bin/activate"
+  else
+    die "Fatal: virtual environment is not a directory"
+  fi
+fi
diff --git a/test/pyproject/pyproject.toml b/test/pyproject/pyproject.toml
new file mode 100644
index 000000000..12ce5e737
--- /dev/null
+++ b/test/pyproject/pyproject.toml
@@ -0,0 +1,6 @@
+# this is not a real pyproject.toml; only enough to run the selftests in CI.
+
+[project]
+dependencies = [
+  "pyyaml==5.1"
+]
diff --git a/test/vulnerable.txt b/test/vulnerable.txt
new file mode 100644
index 000000000..6c05a614d
--- /dev/null
+++ b/test/vulnerable.txt
@@ -0,0 +1 @@
+pyyaml==5.1


[libcloud] 03/03: Add github action to the repo as subtree since ASF policy doesn't allow using external actions.

Posted by to...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch pip_audit_gha_check
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit ca81f08fa5d660b0785f7322f8a483a91403c834
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Fri Sep 2 20:44:32 2022 +0200

    Add github action to the repo as subtree since ASF policy doesn't allow
    using external actions.
---
 .github/workflows/main.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 3ff399ea1..cfc763253 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -208,7 +208,7 @@ jobs:
           python -m pip install .
 
       - name: Run Pip Audit Check
-        uses: pypa/gh-action-pip-audit@cce88443a7a495d91316565f5cc077f815a8f1c7  # v1.0.0
+        uses: ./.github/actions/gh-action-pip-audit/  # v1.0.0
         with:
           virtual-environment: venv/