Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First release #20

Merged
merged 1 commit into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
135 changes: 135 additions & 0 deletions .github/actions/test/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
name: 'Test'
description: 'A GitHub Action that tests this action'

inputs:
os:
description: operating system, e.g. ubuntu-22.04
required: true
python-version:
description: Python version, e.g. 3.11
required: true

runs:
using: 'composite'
steps:
- name: Setup Ubuntu
if: startsWith(inputs.os, 'ubuntu')
run: |
sudo apt-get update
sudo apt-get install language-pack-en language-pack-de
shell: bash

- name: Setup Python
if: inputs.python-version != 'installed'
uses: actions/setup-python@v4
with:
python-version: ${{ inputs.python-version }}

- name: Checkout
uses: actions/checkout@v3

- name: Detect OS
id: os
env:
OS: ${{ inputs.os }}
run: |
case "$OS" in
ubuntu*)
echo "pip-cache=~/.cache/pip" >> $GITHUB_OUTPUT
;;
macos*)
echo "pip-cache=~/Library/Caches/pip" >> $GITHUB_OUTPUT
;;
windows*)
echo "pip-cache=~\\AppData\\Local\\pip\\Cache" >> $GITHUB_OUTPUT
;;
esac
echo "date=$(date +%Y%m%d 2> /dev/null || true)" >> $GITHUB_OUTPUT
shell: bash

- name: Cache PIP Packages
uses: actions/cache@v3
id: cache
with:
path: ${{ steps.os.outputs.pip-cache }}
key: ${{ inputs.os }}-pip-test-${{ inputs.python-version }}-${{ hashFiles('**/requirements.txt', '**/constraints.txt') }}-${{ steps.os.outputs.date }}
restore-keys: |
${{ inputs.os }}-pip-test-${{ inputs.python-version }}-${{ hashFiles('**/requirements.txt', '**/constraints.txt') }}-
${{ inputs.os }}-pip-test-${{ inputs.python-version }}-
${{ inputs.os }}-pip-test-

- name: Install Python dependencies
run: |
python3 -V
python3 -m pip freeze | sort
python3 -m pip cache info || true
python3 -m pip cache list || true
python3 -m pip install --upgrade --force pip wheel
python3 -m pip install --force -r python/requirements.txt
python3 -m pip install --force -r python/test/requirements.txt -c python/test/constraints.txt
python3 -m pip freeze | sort
python3 -m pip cache info || true
python3 -m pip cache list || true
shell: bash

- name: Update expectation files
id: changes
continue-on-error: true
run: |
python/test/files/update_expectations.sh
git status

if ! git diff --exit-code || [[ $(git ls-files -o --exclude-standard | wc -l) -gt 0 ]]
then
# we only upload the changed files if we can find zip
if which zip
then
(git diff --name-only && git ls-files -o --exclude-standard) | xargs -d "\n" zip changed-expectations.zip
exit 1
fi
fi
shell: bash
- name: Upload changed expectation files
if: steps.changes.outcome == 'failure'
uses: actions/upload-artifact@v3
with:
name: Changed expectations
path: changed-expectations.zip
if-no-files-found: error

- name: PyTest
env:
PYTHONPATH: ..
run: |
cd python/test
python3 -m pytest --capture=tee-sys --continue-on-collection-errors --junit-xml ../../test-results/pytest.xml
shell: bash

- name: PyTest (EST)
env:
TZ: US/Eastern
LANG: "en_US.UTF-8"
PYTHONPATH: ..
run: |
cd python/test
python3 -m pytest --capture=tee-sys --continue-on-collection-errors --junit-xml ../../test-results/pytest-est.xml
shell: bash

- name: PyTest (CET)
env:
TZ: Europe/Berlin
LANG: "de_DE.UTF-8"
PYTHONPATH: ..
run: |
cd python/test
python3 -m pytest --capture=tee-sys --continue-on-collection-errors --junit-xml ../../test-results/pytest-cet.xml
shell: bash

- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v3
with:
name: Test Results (python-${{ inputs.python-version }}, ${{ inputs.os }})
path: |
test-results/*.xml
unit-test-results.json
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
13 changes: 13 additions & 0 deletions .github/upgrade-pip-packages.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
set -euo pipefail

base="$(dirname "$0")"

pip install --upgrade --force pip==22.0.0
pip install --upgrade --upgrade-strategy eager -r "$base/../python/requirements-direct.txt"

pip install pipdeptree
pipdeptree --packages="$(sed -e "s/;.*//" -e "s/=.*//g" "$base/../python/requirements-direct.txt" | paste -s -d ,)" --freeze > "$base/../python/requirements.txt"

git diff "$base/../python/requirements.txt"

21 changes: 21 additions & 0 deletions .github/workflows/actions_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Release GitHub Actions

on:
workflow_dispatch:
inputs:
tag:
description: "Tag for the release"
required: true

permissions:
contents: read

jobs:
release:
permissions:
actions: read
id-token: write
contents: write
uses: step-security/reusable-workflows/.github/workflows/actions_release.yaml@v1
with:
tag: "${{ github.event.inputs.tag }}"
203 changes: 203 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
name: CI/CD

on:
push:
branches:
- 'main*'
- 'devel-*'
tags:
- '*'
pull_request:
schedule:
- cron: '0 16 * * *'
workflow_dispatch:
permissions: {}

jobs:
dependencies:
name: Test python/requirements.txt
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Check requirements.txt against requirements-direct.txt
run: |
(diff -w python/requirements-direct.txt python/requirements.txt || true) | (! grep -e "^<")
shell: bash
- name: Check for dependency updates
continue-on-error: true
run:
.github/upgrade-pip-packages.sh
shell: bash

test-mac:
name: "Test macOS"
uses: "./.github/workflows/test-os.yml"
with:
os: '["macos-11", "macos-12", "macos-13"]'

test-lnx:
name: "Test Ubuntu"
uses: "./.github/workflows/test-os.yml"
with:
os: '["ubuntu-20.04", "ubuntu-22.04"]'

test-win:
name: "Test Windows"
uses: "./.github/workflows/test-os.yml"
with:
os: '["windows-2019", "windows-2022"]'

publish:
name: "Publish"
needs: [test-mac, test-lnx, test-win]
# we run the action from this branch whenever we can (when it runs in our repo's context)
if: >
! cancelled() &&
github.event.sender.login != 'dependabot[bot]' &&
( github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository )
uses: "./.github/workflows/publish.yml"
permissions:
checks: write
pull-requests: write
security-events: write

config-deploy:
name: Configure Deployment
needs: [test-mac, test-lnx, test-win]
# do not build or deploy on forked repositories
if: github.repository_owner == 'step-security'
runs-on: ubuntu-latest
outputs:
image: ${{ steps.action.outputs.image }}
image-exists: ${{ steps.image.outputs.exists }}
image-version: ${{ steps.action.outputs.version }}

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Extract action image and version
# we deploy from a specific commit on main (the one that mentions a new version the first time)
# so we need to tell docker/metadata-action to extract docker tags from that version
id: action
run: |
image=$(grep -A 10 "^runs:" action.yml | grep -E "^\s+image:\s" | sed -E -e "s/^\s+image:\s*'//" -e "s/docker:\/\///" -e "s/'\s*$//")
version=$(cut -d : -f 2 <<< "$image")
echo "image=$image" >>$GITHUB_OUTPUT
echo "version=$version" >>$GITHUB_OUTPUT
shell: bash

- name: Check action image existence
id: image
env:
DOCKER_CLI_EXPERIMENTAL: enabled
run: |
exists='false'
if docker manifest inspect '${{ steps.action.outputs.image }}'
then
exists='true'
fi
echo "exists=$exists" >>$GITHUB_OUTPUT
shell: bash

deploy:
name: Deploy to GitHub
needs: [publish, config-deploy]

# do not build or deploy on forked repositories
if: github.repository_owner == 'step-security'
runs-on: ubuntu-latest
permissions:
packages: write
outputs:
image: ${{ steps.image.outputs.image }}
digest: ${{ steps.build.outputs.digest }}
should_push: ${{ steps.check_conditions.outputs.should_push }}
steps:
- name: Docker meta
id: docker-meta
uses: docker/metadata-action@v4
with:
images: ghcr.io/step-security/publish-unit-test-result-action
flavor: |
latest=false
prefix=v
tags: |
type=sha
type=ref,event=tag
type=semver,pattern={{major}},value=${{ needs.config-deploy.outputs.image-version }}
type=semver,pattern={{major}}.{{minor}},value=${{ needs.config-deploy.outputs.image-version }}
type=semver,pattern={{version}},value=${{ needs.config-deploy.outputs.image-version }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Check Conditions
id: check_conditions
run: |
should_push_value='false'
if [[ '${{ github.event_name }}' == 'push' ]]; then
if [[ ${{ startsWith(github.ref, 'refs/heads/main') }} && '${{ needs.config-deploy.outputs.image-exists }}' != 'true' ]]; then
should_push_value='true'
fi
fi
echo "should_push=$should_push_value" >> "$GITHUB_OUTPUT"


- name: Build and push Docker image
uses: docker/build-push-action@v4
id: build
with:
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
pull: true
# deploy image actions from commits pushed to main and
# deploy Dockerfile actions from pushed version tags (no major versions)
push: ${{ steps.check_conditions.outputs.should_push }}
- name: Output image
id: image
env:
IMAGE_REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
run: |
# NOTE: Set the image as an output because the `env` context is not
# available to the inputs of a reusable workflow call.
image_name="${IMAGE_REGISTRY}/${IMAGE_NAME}"
echo "image=$image_name" >> "$GITHUB_OUTPUT"

provenance:
needs: [deploy]
permissions:
actions: read # for detecting the Github Actions environment.
id-token: write # for creating OIDC tokens for signing.
packages: write # for uploading attestations.
if: ${{ needs.deploy.outputs.should_push == 'true' }}
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
with:
image: ${{ needs.deploy.outputs.image }}
digest: ${{ needs.deploy.outputs.digest }}
registry-username: ${{ github.actor }}
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}

event_file:
name: "Event File"
runs-on: ubuntu-latest
steps:
- name: Upload
uses: actions/upload-artifact@v3
with:
name: Event File
path: ${{ github.event_path }}
Loading
Loading