mirror of
https://github.com/ivuorinen/actions.git
synced 2026-01-26 03:23:59 +00:00
feat(ci): versioning change (#378)
* chore: remove bylines from actions * feat: new daily release action * chore(ci): ignore false positive in codeql, fix others * fix: cr comments
This commit is contained in:
16
.github/codeql/codeql-config.yml
vendored
16
.github/codeql/codeql-config.yml
vendored
@@ -15,3 +15,19 @@ paths-ignore:
|
|||||||
# Use security and quality query suite
|
# Use security and quality query suite
|
||||||
queries:
|
queries:
|
||||||
- uses: security-and-quality
|
- uses: security-and-quality
|
||||||
|
|
||||||
|
# Suppress specific false positives
|
||||||
|
# These findings have been manually reviewed and determined to be false positives
|
||||||
|
# with appropriate security controls in place
|
||||||
|
query-filters:
|
||||||
|
# docker-publish: Code injection in validated context
|
||||||
|
# False positive: User input is validated and sanitized before use
|
||||||
|
# - Only relative paths and trusted git URLs are allowed
|
||||||
|
# - Absolute paths and arbitrary URLs are rejected
|
||||||
|
# - Path traversal attempts are blocked
|
||||||
|
# - Custom contexts require explicit opt-in via use-custom-context: true
|
||||||
|
# - Wraps docker/build-push-action (trusted Docker-maintained action)
|
||||||
|
# - Action is designed for trusted workflows only (documented in action.yml)
|
||||||
|
- exclude:
|
||||||
|
id: js/actions/code-injection
|
||||||
|
kind: problem
|
||||||
|
|||||||
1
.github/workflows/codeql-new.yml
vendored
1
.github/workflows/codeql-new.yml
vendored
@@ -42,4 +42,5 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
language: ${{ matrix.language }}
|
language: ${{ matrix.language }}
|
||||||
queries: security-and-quality
|
queries: security-and-quality
|
||||||
|
config-file: .github/codeql/codeql-config.yml
|
||||||
token: ${{ github.token }}
|
token: ${{ github.token }}
|
||||||
|
|||||||
41
.github/workflows/new-release.yml
vendored
41
.github/workflows/new-release.yml
vendored
@@ -22,27 +22,28 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e # v6-beta
|
- uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e # v6-beta
|
||||||
|
|
||||||
- name: Create tag if necessary
|
- name: Create daily release
|
||||||
uses: fregante/daily-version-action@fb1a60b7c4daf1410cd755e360ebec3901e58588 # v2.1.3
|
|
||||||
id: daily-version
|
id: daily-version
|
||||||
with:
|
run: |
|
||||||
prefix: v
|
set -eu
|
||||||
|
|
||||||
- name: Create changelog text
|
VERSION="v$(date '+%Y.%m.%d')"
|
||||||
if: steps.daily-version.outputs.created
|
printf '%s\n' "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||||
id: changelog
|
|
||||||
uses: loopwerk/tag-changelog@941366edb8920e2071eae0449031830984b9f26e # v1.3.0
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
config_file: .github/tag-changelog-config.js
|
|
||||||
|
|
||||||
- name: Create release
|
# Check if release already exists
|
||||||
if: steps.daily-version.outputs.created
|
if gh release view "$VERSION" >/dev/null 2>&1; then
|
||||||
uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1.20.0
|
printf '%s\n' "created=false" >> "$GITHUB_OUTPUT"
|
||||||
|
printf '%s\n' "Release $VERSION already exists - skipping"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create release with auto-generated changelog (also creates tag)
|
||||||
|
gh release create "$VERSION" \
|
||||||
|
--title "Release $VERSION" \
|
||||||
|
--generate-notes \
|
||||||
|
--target main
|
||||||
|
|
||||||
|
printf '%s\n' "created=true" >> "$GITHUB_OUTPUT"
|
||||||
|
printf '%s\n' "Created release $VERSION"
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
|
||||||
tag: ${{ steps.daily-version.outputs.version }}
|
|
||||||
name: Release ${{ steps.daily-version.outputs.version }}
|
|
||||||
body: ${{ steps.changelog.outputs.changes }}
|
|
||||||
allowUpdates: true
|
|
||||||
|
|||||||
4
.github/workflows/version-maintenance.yml
vendored
4
.github/workflows/version-maintenance.yml
vendored
@@ -68,8 +68,6 @@ jobs:
|
|||||||
```bash
|
```bash
|
||||||
make check-version-refs
|
make check-version-refs
|
||||||
```
|
```
|
||||||
|
|
||||||
🤖 Auto-generated by version-maintenance workflow
|
|
||||||
branch: automated/version-update-${{ steps.version.outputs.major }}
|
branch: automated/version-update-${{ steps.version.outputs.major }}
|
||||||
delete-branch: true
|
delete-branch: true
|
||||||
labels: |
|
labels: |
|
||||||
@@ -120,8 +118,6 @@ jobs:
|
|||||||
\`\`\`bash
|
\`\`\`bash
|
||||||
make check-version-refs
|
make check-version-refs
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
🤖 Auto-generated by version-maintenance workflow
|
|
||||||
`,
|
`,
|
||||||
labels: ['maintenance', 'high-priority']
|
labels: ['maintenance', 'high-priority']
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -76,11 +76,7 @@ if ! git diff --quiet; then
|
|||||||
git commit -m "chore: bump major version from $OLD_VERSION to $NEW_VERSION
|
git commit -m "chore: bump major version from $OLD_VERSION to $NEW_VERSION
|
||||||
|
|
||||||
This commit updates all internal action references from $OLD_VERSION
|
This commit updates all internal action references from $OLD_VERSION
|
||||||
to $NEW_VERSION.
|
to $NEW_VERSION."
|
||||||
|
|
||||||
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
||||||
|
|
||||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
||||||
|
|
||||||
printf '%b' "${GREEN}✅ Committed version bump${NC}\n"
|
printf '%b' "${GREEN}✅ Committed version bump${NC}\n"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ runs:
|
|||||||
find . -maxdepth 2 -name "action.yml" -path "*/action.yml" ! -path "./_*" ! -path "./.github/*" -exec grep -h "uses: ivuorinen/actions/" {} \; > "$temp_file"
|
find . -maxdepth 2 -name "action.yml" -path "*/action.yml" ! -path "./_*" ! -path "./.github/*" -exec grep -h "uses: ivuorinen/actions/" {} \; > "$temp_file"
|
||||||
|
|
||||||
while IFS= read -r line; do
|
while IFS= read -r line; do
|
||||||
current_sha=$(echo "$line" | grep -oE '@[a-f0-9]{40}' | sed 's/@//')
|
current_sha=$(printf '%s' "$line" | grep -oE '@[a-f0-9]{40}' | sed 's/@//')
|
||||||
|
|
||||||
if [ "$current_sha" != "$TAG_SHA" ]; then
|
if [ "$current_sha" != "$TAG_SHA" ]; then
|
||||||
echo "Found outdated reference: $current_sha (should be $TAG_SHA)"
|
echo "Found outdated reference: $current_sha (should be $TAG_SHA)"
|
||||||
@@ -153,11 +153,7 @@ runs:
|
|||||||
git commit -m "chore: update action references to $MAJOR_VERSION ($TAG_SHA)" \
|
git commit -m "chore: update action references to $MAJOR_VERSION ($TAG_SHA)" \
|
||||||
-m "" \
|
-m "" \
|
||||||
-m "This commit updates all internal action references to point to the latest" \
|
-m "This commit updates all internal action references to point to the latest" \
|
||||||
-m "$MAJOR_VERSION tag SHA." \
|
-m "$MAJOR_VERSION tag SHA."
|
||||||
-m "" \
|
|
||||||
-m "🤖 Generated with [Claude Code](https://claude.com/claude-code)" \
|
|
||||||
-m "" \
|
|
||||||
-m "Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
||||||
|
|
||||||
commit_sha=$(git rev-parse HEAD)
|
commit_sha=$(git rev-parse HEAD)
|
||||||
printf '%s\n' "sha=$commit_sha" >> "$GITHUB_OUTPUT"
|
printf '%s\n' "sha=$commit_sha" >> "$GITHUB_OUTPUT"
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ runs:
|
|||||||
dockerhub|github|both)
|
dockerhub|github|both)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "::error::Invalid registry value. Must be 'dockerhub', 'github', or 'both'"
|
printf '%s\n' "::error::Invalid registry value. Must be 'dockerhub', 'github', or 'both'"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -120,7 +120,7 @@ runs:
|
|||||||
# Validate Docker Hub credentials if needed
|
# Validate Docker Hub credentials if needed
|
||||||
if [ "$INPUT_REGISTRY" = "dockerhub" ] || [ "$INPUT_REGISTRY" = "both" ]; then
|
if [ "$INPUT_REGISTRY" = "dockerhub" ] || [ "$INPUT_REGISTRY" = "both" ]; then
|
||||||
if [ -z "$INPUT_DOCKERHUB_USERNAME" ] || [ -z "$INPUT_DOCKERHUB_TOKEN" ]; then
|
if [ -z "$INPUT_DOCKERHUB_USERNAME" ] || [ -z "$INPUT_DOCKERHUB_TOKEN" ]; then
|
||||||
echo "::error::Docker Hub username and token are required when publishing to Docker Hub"
|
printf '%s\n' "::error::Docker Hub username and token are required when publishing to Docker Hub"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -129,46 +129,77 @@ runs:
|
|||||||
if [ "$INPUT_REGISTRY" = "github" ] || [ "$INPUT_REGISTRY" = "both" ]; then
|
if [ "$INPUT_REGISTRY" = "github" ] || [ "$INPUT_REGISTRY" = "both" ]; then
|
||||||
token="${INPUT_TOKEN:-${GITHUB_TOKEN:-}}"
|
token="${INPUT_TOKEN:-${GITHUB_TOKEN:-}}"
|
||||||
if [ -z "$token" ]; then
|
if [ -z "$token" ]; then
|
||||||
echo "::error::GitHub token is required when publishing to GitHub Packages"
|
printf '%s\n' "::error::GitHub token is required when publishing to GitHub Packages"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Validate context input for security
|
# Validate context input for security
|
||||||
INPUT_CONTEXT="${INPUT_CONTEXT:-.}"
|
INPUT_CONTEXT="${INPUT_CONTEXT:-.}"
|
||||||
|
|
||||||
case "$INPUT_CONTEXT" in
|
case "$INPUT_CONTEXT" in
|
||||||
.|./*|*/*)
|
.|./*|*/*)
|
||||||
# Relative paths are allowed
|
# Relative paths are allowed
|
||||||
|
# Check for path traversal attempts
|
||||||
|
case "$INPUT_CONTEXT" in
|
||||||
|
*/../*|../*|*/..)
|
||||||
|
printf '%s\n' "::error::Context path contains path traversal: '$INPUT_CONTEXT'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
/*)
|
/*)
|
||||||
echo "::error::Context cannot be an absolute path: '$INPUT_CONTEXT'"
|
printf '%s\n' "::error::Context cannot be an absolute path: '$INPUT_CONTEXT'"
|
||||||
echo "::error::Use relative paths (e.g., '.', './app') to prevent code injection"
|
printf '%s\n' "::error::Use relative paths (e.g., '.', './app')"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
*://*)
|
git://*|git@*|https://*.git|https://github.com/*|https://gitlab.com/*)
|
||||||
echo "::warning::Context is a remote URL: '$INPUT_CONTEXT'"
|
# Allow trusted git repository URLs
|
||||||
echo "::warning::Ensure this URL is from a trusted source to prevent code injection"
|
printf '%s\n' "::notice::Using git repository URL for context"
|
||||||
|
;;
|
||||||
|
http://*|https://*)
|
||||||
|
printf '%s\n' "::error::Context cannot be an arbitrary HTTP URL: '$INPUT_CONTEXT'"
|
||||||
|
printf '%s\n' "::error::Only git repository URLs are allowed for remote contexts"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf '%s\n' "::error::Invalid context format: '$INPUT_CONTEXT'"
|
||||||
|
printf '%s\n' "::error::Must be a relative path or git repository URL"
|
||||||
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Validate dockerfile input for security
|
# Validate dockerfile input for security
|
||||||
INPUT_DOCKERFILE="${INPUT_DOCKERFILE:-Dockerfile}"
|
INPUT_DOCKERFILE="${INPUT_DOCKERFILE:-Dockerfile}"
|
||||||
|
|
||||||
case "$INPUT_DOCKERFILE" in
|
case "$INPUT_DOCKERFILE" in
|
||||||
Dockerfile|*/Dockerfile|*.dockerfile|*/*.dockerfile)
|
Dockerfile|*/Dockerfile|*.dockerfile|*/*.dockerfile)
|
||||||
# Common dockerfile patterns are allowed
|
# Common dockerfile patterns are allowed
|
||||||
|
# Check for path traversal attempts
|
||||||
|
case "$INPUT_DOCKERFILE" in
|
||||||
|
*/../*|../*|*/..)
|
||||||
|
printf '%s\n' "::error::Dockerfile path contains path traversal: '$INPUT_DOCKERFILE'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
/*)
|
/*)
|
||||||
echo "::error::Dockerfile path cannot be absolute: '$INPUT_DOCKERFILE'"
|
printf '%s\n' "::error::Dockerfile path cannot be absolute: '$INPUT_DOCKERFILE'"
|
||||||
echo "::error::Use relative paths (e.g., 'Dockerfile', './docker/Dockerfile')"
|
printf '%s\n' "::error::Use relative paths (e.g., 'Dockerfile', './docker/Dockerfile')"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
*://*)
|
*://*)
|
||||||
echo "::error::Dockerfile path cannot be a URL: '$INPUT_DOCKERFILE'"
|
printf '%s\n' "::error::Dockerfile path cannot be a URL: '$INPUT_DOCKERFILE'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf '%s\n' "::error::Invalid Dockerfile format: '$INPUT_DOCKERFILE'"
|
||||||
|
printf '%s\n' "::error::Must be 'Dockerfile', '*/Dockerfile', '*.dockerfile', or '*/*.dockerfile'"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo "Input validation completed successfully"
|
printf '%s\n' "Input validation completed successfully"
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
@@ -223,14 +254,14 @@ runs:
|
|||||||
# Output results
|
# Output results
|
||||||
printf 'image-name=%s\n' "$base_name" >> "$GITHUB_OUTPUT"
|
printf 'image-name=%s\n' "$base_name" >> "$GITHUB_OUTPUT"
|
||||||
{
|
{
|
||||||
echo 'tags<<EOF'
|
printf '%s\n' 'tags<<EOF'
|
||||||
echo "$tags"
|
printf '%s\n' "$tags"
|
||||||
echo 'EOF'
|
printf '%s\n' 'EOF'
|
||||||
} >> "$GITHUB_OUTPUT"
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
echo "Image name: $base_name"
|
printf 'Image name: %s\n' "$base_name"
|
||||||
echo "Tags:"
|
printf '%s\n' "Tags:"
|
||||||
echo "$tags"
|
printf '%s\n' "$tags"
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
if: inputs.registry == 'dockerhub' || inputs.registry == 'both'
|
if: inputs.registry == 'dockerhub' || inputs.registry == 'both'
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ runs:
|
|||||||
uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e # v6-beta
|
uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e # v6-beta
|
||||||
with:
|
with:
|
||||||
token: ${{ inputs.token || github.token }}
|
token: ${{ inputs.token || github.token }}
|
||||||
ref: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref_name }}
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
# If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to
|
# If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to
|
||||||
@@ -729,13 +729,6 @@ runs:
|
|||||||
- name: Prepare commit
|
- name: Prepare commit
|
||||||
if: env.APPLY_FIXES_IF_COMMIT == 'true'
|
if: env.APPLY_FIXES_IF_COMMIT == 'true'
|
||||||
shell: sh
|
shell: sh
|
||||||
env:
|
|
||||||
BRANCH_REF: >-
|
|
||||||
${{
|
|
||||||
github.event.pull_request.head.ref ||
|
|
||||||
github.head_ref ||
|
|
||||||
github.ref_name
|
|
||||||
}}
|
|
||||||
run: |
|
run: |
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
@@ -747,27 +740,38 @@ runs:
|
|||||||
# This is necessary because MegaLinter may leave the repo in a detached HEAD state
|
# This is necessary because MegaLinter may leave the repo in a detached HEAD state
|
||||||
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||||
if [ "$current_branch" = "HEAD" ]; then
|
if [ "$current_branch" = "HEAD" ]; then
|
||||||
echo "Repository is in detached HEAD state, checking out $BRANCH_REF"
|
printf '%s\n' "Repository is in detached HEAD state"
|
||||||
# Validate branch reference to prevent command injection
|
|
||||||
if ! git check-ref-format --branch "$BRANCH_REF"; then
|
# Get the branch name from git refs (safer than trusting event data)
|
||||||
echo "::error::Invalid branch reference format: $BRANCH_REF"
|
# This finds the branch that points to the current commit
|
||||||
|
branch_ref=$(git for-each-ref --format='%(refname:short)' --points-at=HEAD 'refs/remotes/origin/*' | head -1 | sed 's|^origin/||')
|
||||||
|
|
||||||
|
if [ -z "$branch_ref" ]; then
|
||||||
|
echo "::error::Could not determine branch name from git refs"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
git checkout "$BRANCH_REF"
|
|
||||||
|
# Validate branch reference to prevent command injection
|
||||||
|
if ! git check-ref-format --branch "$branch_ref"; then
|
||||||
|
echo "::error::Invalid branch reference format: $branch_ref"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Checking out branch: $branch_ref"
|
||||||
|
git checkout "$branch_ref"
|
||||||
|
|
||||||
|
# Export for next step
|
||||||
|
echo "VALIDATED_BRANCH=$branch_ref" >> "$GITHUB_ENV"
|
||||||
else
|
else
|
||||||
echo "Repository is on branch: $current_branch"
|
echo "Repository is on branch: $current_branch"
|
||||||
|
echo "VALIDATED_BRANCH=$current_branch" >> "$GITHUB_ENV"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Commit and push applied linter fixes
|
- name: Commit and push applied linter fixes
|
||||||
uses: stefanzweifel/git-auto-commit-action@28e16e81777b558cc906c8750092100bbb34c5e3 # v7.0.0
|
uses: stefanzweifel/git-auto-commit-action@28e16e81777b558cc906c8750092100bbb34c5e3 # v7.0.0
|
||||||
if: env.APPLY_FIXES_IF_COMMIT == 'true'
|
if: env.APPLY_FIXES_IF_COMMIT == 'true'
|
||||||
with:
|
with:
|
||||||
branch: >-
|
branch: ${{ env.VALIDATED_BRANCH }}
|
||||||
${{
|
|
||||||
github.event.pull_request.head.ref ||
|
|
||||||
github.head_ref ||
|
|
||||||
github.ref
|
|
||||||
}}
|
|
||||||
commit_message: 'style: apply linter fixes'
|
commit_message: 'style: apply linter fixes'
|
||||||
commit_user_name: ${{ inputs.username }}
|
commit_user_name: ${{ inputs.username }}
|
||||||
commit_user_email: ${{ inputs.email }}
|
commit_user_email: ${{ inputs.email }}
|
||||||
|
|||||||
Reference in New Issue
Block a user