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

SC-21584: Flow improvements + Security #104

Merged
merged 8 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/compare-images.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/bin/bash

if [ -z "$1" ]; then
echo "Error: No tag provided. Usage: ./compare-image.sh <docker-tag>"
exit 1
fi

IMAGE_TAG=$1

if [[ "$IMAGE_TAG" == *"debian"* ]]; then
docker run -i --rm "$IMAGE_TAG" sh -s <<'EOF'
echo "=== Debian Version ==="
echo -n "Debian " && cat /etc/debian_version

echo ""
echo "=== Installed PHP Extensions ==="
docker-php-source extract
for ext in `ls /usr/src/php/ext`; do
echo ' ' `php -r "if (extension_loaded('$ext' !== 'opcache' ? '$ext' : 'Zend OPcache')) { echo '[x] $ext'; } else { echo '[ ] $ext'; }"`;
done

echo ""
echo "=== Disabled PHP Extensions ==="
for f in /usr/local/etc/php/disabled/*.ini; do
disabled=$(basename $f | sed -e 's/\.ini$//');
echo " [ ] ${disabled} $(PHP_INI_SCAN_DIR=:/usr/local/etc/php/disabled php -r "echo phpversion('${disabled}');")";
done

echo ""
echo "=== PECL Extensions ==="
pear list -c pecl

echo ""
echo "=== Composer Version ==="
composer -V

echo ""
echo "=== Installed System Packages ==="
dpkg-query -W --showformat='${Package} ${Version}\n' | sort
EOF
else
docker run -i --rm "$IMAGE_TAG" sh -s <<'EOF'
echo "=== Alpine Version ==="
echo -n "Alpine " && cat /etc/alpine-release

echo ""
echo "=== Installed PHP Extensions ==="
docker-php-source extract
for ext in `ls /usr/src/php/ext`; do
echo ' ' `php -r "if (extension_loaded('$ext' !== 'opcache' ? '$ext' : 'Zend OPcache')) { echo '[x] $ext'; } else { echo '[ ] $ext'; }"`;
done

echo ""
echo "=== Disabled PHP Extensions ==="
for f in /usr/local/etc/php/disabled/*.ini; do
disabled=$(basename $f | sed -e 's/\.ini$//');
echo " [ ] ${disabled} $(PHP_INI_SCAN_DIR=:/usr/local/etc/php/disabled php -r "echo phpversion('${disabled}');")";
done

echo ""
echo "=== PECL Extensions ==="
pear list -c pecl

echo ""
echo "=== Composer Version ==="
composer -V

echo ""
echo "=== Installed System Packages ==="
apk info -vv | sort
EOF
fi

85 changes: 69 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
name: CI
name: CI/CD

on: push

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -10,17 +14,6 @@ jobs:
matrix:
include:
## Alpine
### Alpine 3.17
- image: "alpine/3.17/8.1/Dockerfile"
tags: [ "spryker/php:8.1-alpine3.17" ]
platforms: [ "linux/amd64", "linux/arm64" ]
- image: "alpine/3.17/8.2/Dockerfile"
tags: [ "spryker/php:8.2-alpine3.17" ]
platforms: [ "linux/amd64", "linux/arm64" ]
- image: "alpine/3.17/8.3/Dockerfile"
tags: [ "spryker/php:8.3-alpine3.17" ]
platforms: [ "linux/amd64", "linux/arm64" ]

### Alpine 3.18
- image: "alpine/3.18/8.1/Dockerfile"
tags: [ "spryker/php:8.1-alpine3.18" ]
Expand Down Expand Up @@ -68,6 +61,7 @@ jobs:
- image: "debian/bullseye/8.3/Dockerfile"
tags: [ "spryker/php:8.3-debian" ]
platforms: [ "linux/amd64", "linux/arm64" ]

steps:
- name: Check out repository
uses: actions/checkout@v3
Expand All @@ -76,10 +70,23 @@ jobs:

- name: Get the previous commit hash
id: previous_commit
if: ${{ github.ref == 'refs/heads/master' }}
run: |
PREV_COMMIT_HASH=$(git rev-parse HEAD^1)
echo "PREV_COMMIT_HASH=$PREV_COMMIT_HASH" >> $GITHUB_ENV
if [ "${{ github.ref }}" == "refs/heads/master" ]; then
PREV_COMMIT_HASH=$(git rev-parse HEAD^1)
else
PREV_COMMIT_HASH=$(git rev-parse origin/master)
IMAGE_TAG="${{ matrix.tags[0] }}"
echo "Pulling image $IMAGE_TAG"
docker pull "$IMAGE_TAG"

NEW_TAG="${IMAGE_TAG}-${PREV_COMMIT_HASH}"
echo "Re-tagging image to $NEW_TAG"
docker tag "$IMAGE_TAG" "$NEW_TAG"

echo "Removing the pulled image $IMAGE_TAG"
docker rmi "$IMAGE_TAG" || true
fi
echo "PREV_COMMIT_HASH=$PREV_COMMIT_HASH" >> $GITHUB_ENV

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
Expand Down Expand Up @@ -111,6 +118,52 @@ jobs:
uses: docker/build-push-action@v2
with:
push: ${{ github.ref == 'refs/heads/master' }}
load: ${{ github.ref != 'refs/heads/master' }}
file: ${{ matrix.image }}
tags: ${{ join(matrix.tags) }}
platforms: ${{ join(matrix.platforms) }}
platforms: ${{ github.ref == 'refs/heads/master' && join(matrix.platforms) || 'linux/amd64' }}

- name: Current image report
run: |
CURRENT_TAG=${{ matrix.tags[0] }}
bash .github/compare-images.sh $CURRENT_TAG > current-image-report.txt || true
cat current-image-report.txt

- name: Previous image report
run: |
PREVIOUS_TAG="${{ matrix.tags[0] }}-${{ env.PREV_COMMIT_HASH }}"
bash .github/compare-images.sh $PREVIOUS_TAG > previous-image-report.txt || true
cat previous-image-report.txt

- name: Run the diff
run: |
DIFF_OUTPUT=$(diff current-image-report.txt previous-image-report.txt | sed ':a;N;$!ba;s/\n/\\n/g' || true)
echo "$DIFF_OUTPUT"

echo "DIFF_OUTPUT<<EOF" >> $GITHUB_ENV
echo "$DIFF_OUTPUT" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV

- name: Send Slack Notification
if: ${{ github.ref == 'refs/heads/master' && env.DIFF_OUTPUT != '' }}
uses: slackapi/[email protected]
with:
payload: |
{
"attachments": [
{
"pretext": "Release changes for *spryker/php:${{ matrix.tags[0] }}*",
"color": "good",
"fields": [
{
"title": "Image diff:",
"value": "${{ env.DIFF_OUTPUT }}",
"short": false
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
103 changes: 103 additions & 0 deletions .github/workflows/cleanup-old-docker-images.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Cleanup Old Docker Images > 6 months by the scheduler

on:
push:
branches:
- master

jobs:
cleanup:
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v2

- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: List Docker Hub images and delete ones matching the pattern
run: |
REPO="spryker/php"
curl -s "https://hub.docker.com/v2/repositories/${REPO}/tags?page_size=1000" > tags.json
TODAY=$(date +%s)
THRESHOLD=$((180 * 24 * 60 * 60)) # 180 days in seconds

# Regex pattern to match tags that end with a hash (40-character hexadecimal)
HASH_PATTERN=".*-[a-f0-9]{40}$"
IMAGES_DELETED=false
DELETED_IMAGES=""

for TAG in $(jq -r '.results[] | @base64' < tags.json); do
_jq() {
echo ${TAG} | base64 --decode | jq -r ${1}
}

TAG_NAME=$(_jq '.name')
LAST_UPDATED=$(_jq '.last_updated')
LAST_UPDATED_DATE=$(date -d "${LAST_UPDATED}" +%s)

AGE=$((TODAY - LAST_UPDATED_DATE))

if [[ ${AGE} -ge ${THRESHOLD} ]] && [[ ${TAG_NAME} =~ ${HASH_PATTERN} ]]; then
echo "Deleting image tag ${TAG_NAME} (last updated: ${LAST_UPDATED})"
IMAGES_DELETED=true
DELETED_IMAGES="${DELETED_IMAGES}\n${TAG_NAME}"

# Uncomment the following lines to enable image deletion
curl -X DELETE \
-u "${{ secrets.DOCKER_USERNAME }}:${{ secrets.DOCKER_PASSWORD }}" \
"https://hub.docker.com/v2/repositories/${REPO}/tags/${TAG_NAME}/"
fi
done

if [[ ${IMAGES_DELETED} == false ]]; then
echo "No images found for deletion" > deleted_images.txt
else
echo -e "Deleted images: ${DELETED_IMAGES}" > deleted_images.txt
fi

- name: Read Deleted Images
id: read_deleted_images
run: |
DELETED_IMAGES=$(cat deleted_images.txt)
echo "Deleted images: ${DELETED_IMAGES}"
echo "::set-output name=deleted_images::${DELETED_IMAGES}"
shell: bash

- name: Send Slack Notification
uses: slackapi/[email protected]
if: ${{ github.ref == 'refs/heads/master' }}
with:
payload: |
{
"attachments": [
{
"pretext": "Outdated docker images cleanup (180 days) for *${{ github.repository }} repository*",
"color": "good",
"fields": [
{
"title": "Images:",
"value": "${{ steps.read_deleted_images.outputs.deleted_images }}",
"short": false
},
{
"title": "Branch:",
"value": "${{ github.ref }}",
"short": true
},
{
"title": "Commit:",
"value": "${{ github.sha }}",
"short": true
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Vulnerability detection
name: ECR vulnerability detection

on:
schedule:
- cron: '0 9 * * *'
push:
branches-ignore:
branches:
- master

jobs:
Expand All @@ -15,17 +15,6 @@ jobs:
matrix:
include:
## Alpine
### Alpine 3.17
- image: "alpine/3.17/8.1/Dockerfile"
tags: "8.1-alpine3.17"
platforms: "linux/amd64"
- image: "alpine/3.17/8.2/Dockerfile"
tags: "8.2-alpine3.17"
platforms: "linux/amd64"
- image: "alpine/3.17/8.3/Dockerfile"
tags: "8.3-alpine3.17"
platforms: "linux/amd64"

### Alpine 3.18
- image: "alpine/3.18/8.1/Dockerfile"
tags: "8.1-alpine3.18"
Expand Down Expand Up @@ -119,7 +108,7 @@ jobs:
"text": "Scanned image tag *${{ matrix.tags }}*.",
"attachments": [
{
"pretext": "Vulnerability scan outputs for ${{ steps.set-date.outputs.current_datetime }}",
"pretext": "ECR vulnerability scan outputs for ${{ steps.set-date.outputs.current_datetime }}",
"color": "${{ steps.set-color.outputs.color }}",
"fields": [
{
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/trivy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Trivy secrets scan

on:
push:
branches-ignore:
- master

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
trivy-secrets-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Scan for secrets in repository
uses: aquasecurity/[email protected]
with:
scan-type: 'fs'
trivy-config: .trivy/trivy.yaml
Loading
Loading