Skip to content

Reverse-Engineer Case Studies #332

Reverse-Engineer Case Studies

Reverse-Engineer Case Studies #332

name: Reverse-Engineer Case Studies
on:
workflow_dispatch:
inputs:
overrideBenchmark:
description: "Override parameter 'benchmark' to true (use hyperfine)"
required: false
default: "false"
type: "string"
analyzeVulnerabilities:
description: "Analyze vulnerabilities (use snyk)"
required: false
default: "false"
type: "string"
# Every day at 2:00.
schedule:
- cron: "0 2 * * *"
permissions:
contents: write
jobs:
collect_info:
runs-on: ubuntu-latest
outputs:
array: ${{ steps.find_directories.outputs.array }}
latest_version: ${{ steps.latest_version.outputs.value }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Find directories
id: find_directories
run: |
array=$( \
printf '[%s]' "$(find . -maxdepth 1 -type d -exec test -e "{}/.retriever.yml" ';' -printf '"%P",' | sed 's/\.\///g; s/,$//')" \
)
echo "array=$array" >> $GITHUB_OUTPUT
- name: Get latest Retriever version
id: latest_version
run: |
LATEST_VERSION=$(\
curl -sL ${{ github.api_url }}/repos/PalladioSimulator/Palladio-ReverseEngineering-Retriever/releases/latest \
| jq -r ".tag_name"
)
echo "value=$LATEST_VERSION" >> $GITHUB_OUTPUT
generate_pcm:
runs-on: ubuntu-latest
needs: collect_info
continue-on-error: true
strategy:
fail-fast: false
max-parallel: ${{ inputs.analyzeVulnerabilities == 'true' && 1 || 1000 }}
matrix:
directory: ${{ fromJson(needs.collect_info.outputs.array) }}
steps:
- name: Checkout benchmark repository
uses: actions/checkout@v3
with:
path: benchmark
- name: Install yq
run: |
wget https://github.com/mikefarah/yq/releases/download/v4.2.0/yq_linux_amd64.tar.gz -O - \
| tar xz && sudo mv yq_linux_amd64 /usr/bin/yq
- name: Parse .retriever.yml
run: |
CONFIG_FILE="benchmark/${{ matrix.directory }}/.retriever.yml"
# create comma-separated list of repositories
readarray -t repos < <(yq e '.repository' "$CONFIG_FILE" | sed 's/- //g')
repos_str=$(IFS=,; echo "${repos[*]}")
echo "repositories=$repos_str" >> $GITHUB_ENV
echo "current_version=$(yq eval '.current_version' $CONFIG_FILE)" >> $GITHUB_ENV
echo "rules=$(yq eval '.rules[]' $CONFIG_FILE | paste -sd ",")" >> $GITHUB_ENV
if [ -f "benchmark/${{ matrix.directory }}/ProjectSpecificRules.xtend" ]; then
echo "rules_path=benchmark/${{ matrix.directory }}" >> $GITHUB_ENV
else
echo "rules_path=" >> $GITHUB_ENV
fi
# Check for overrideBenchmark input
if [ "${{ github.event.inputs.overrideBenchmark }}" == "true" ]; then
echo "benchmark="true"" >> $GITHUB_ENV
else
echo "benchmark=$(yq eval '.benchmark // "false"' $CONFIG_FILE)" >> $GITHUB_ENV
fi
- name: Check for gold standard
run: |
# only analyze vulnerabilities if a gold standard is present
if [ -d "benchmark/${{ matrix.directory }}/model_gs" ]; then
echo "analyze_vulnerabilities=${{ github.event.inputs.analyzeVulnerabilities }}" >> $GITHUB_ENV
else
echo "analyze_vulnerabilities="false"" >> $GITHUB_ENV
fi
- name: Checkout repositories
if: ${{ needs.collect_info.outputs.latest_version != env.current_version || inputs.overrideBenchmark == 'true' || env.analyze_vulnerabilities == 'true' }}
run: |
# Assuming repositories is a comma-separated list
IFS=',' read -r -a repositories_array <<< "${{ env.repositories }}"
for REPOSITORY in "${repositories_array[@]}"; do
REPO_NAME=$(basename "$REPOSITORY")
echo "Checking out $REPOSITORY to repo/${{ matrix.directory }}/$REPO_NAME"
git clone https://github.com/"$REPOSITORY" "repo/${{ matrix.directory }}/$REPO_NAME" --depth=1
done
- name: Run Retriever
if: ${{ needs.collect_info.outputs.latest_version != env.current_version || inputs.overrideBenchmark == 'true' || env.analyze_vulnerabilities == 'true' }}
uses: PalladioSimulator/Palladio-ReverseEngineering-Retriever@main
with:
source_path: repo/${{ matrix.directory }}
rules: ${{ env.rules }}
analyze_vulnerabilities: ${{ env.analyze_vulnerabilities }}
snyk_token: ${{ secrets.SNYK_TOKEN }}
nist_nvd_token: ${{ secrets.NVD_TOKEN }}
benchmark: ${{ env.benchmark }}
rules_path: ${{ env.rules_path }}
- name: Download results
if: ${{ needs.collect_info.outputs.latest_version != env.current_version || inputs.overrideBenchmark == 'true' || env.analyze_vulnerabilities == 'true' }}
uses: actions/download-artifact@v3
with:
name: retriever
path: results
- name: Prepare upload
if: ${{ needs.collect_info.outputs.latest_version != env.current_version || inputs.overrideBenchmark == 'true' || env.analyze_vulnerabilities == 'true' }}
run: |
mkdir -p to_commit/${{ matrix.directory }}/model_re/pcm
mkdir -p to_commit/${{ matrix.directory }}/model_re/uml
mkdir -p to_commit/${{ matrix.directory }}/model_re/snyk
mv results/repo/${{ matrix.directory }}/*.puml to_commit/${{ matrix.directory }}/model_re/uml
# Move snyk *.log files, if there are any.
find results/repo/${{ matrix.directory }} -maxdepth 1 -name "*.log" -exec mv -t to_commit/${{ matrix.directory }}/model_re/snyk {} +
mv results/repo/${{ matrix.directory }}/*.md to_commit/${{ matrix.directory }}/model_re/
mv results/repo/${{ matrix.directory }}/* to_commit/${{ matrix.directory }}/model_re/pcm
- name: Render UML diagrams
if: ${{ needs.collect_info.outputs.latest_version != env.current_version || inputs.overrideBenchmark == 'true' || env.analyze_vulnerabilities == 'true' }}
run: |
sudo apt-get install graphviz
wget https://github.com/plantuml/plantuml/releases/download/v1.2023.13/plantuml-1.2023.13.jar -O plantuml.jar
shopt -s nullglob
for file in to_commit/${{ matrix.directory }}/model_re/uml/*.puml; do
[ -f "$file" ] || continue
java -jar plantuml.jar -tsvg "$file" || echo "Diagram description contains errors: ${file}"
done
- name: Update version
if: ${{ needs.collect_info.outputs.latest_version != env.current_version || inputs.overrideBenchmark == 'true' || env.analyze_vulnerabilities == 'true' }}
run: |
# manually overwrite current_version to avoid bug with yq
sed -i 's/current_version:.*/current_version: "${{ needs.collect_info.outputs.latest_version }}"/' "benchmark/${{ matrix.directory }}/.retriever.yml"
# yq '.current_version = "${{ needs.collect_info.outputs.latest_version }}"' -i "benchmark/${{ matrix.directory }}/.retriever.yml"
mv "benchmark/${{ matrix.directory }}/.retriever.yml" to_commit/${{ matrix.directory }}/.retriever.yml
- name: Upload artifact
if: ${{ needs.collect_info.outputs.latest_version != env.current_version || inputs.overrideBenchmark == 'true' || env.analyze_vulnerabilities == 'true' }}
uses: actions/upload-artifact@v3
with:
name: to_commit
path: to_commit
commit_results:
runs-on: ubuntu-latest
needs:
- collect_info
- generate_pcm
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
path: repo
- name: Download artifact
id: download_artifact
uses: actions/download-artifact@v3
continue-on-error: true
with:
name: to_commit
path: to_commit
- name: Integrate changes
if: steps.download_artifact.outcome == 'success'
run: |
rsync -a to_commit/* repo
cd repo
git config user.name "GitHub Actions"
git config user.email "[email protected]"
git add .
git commit -m "Upload analysis (Retriever ${{ needs.collect_info.outputs.latest_version }})"
git push
- name: Trigger repository_dispatch event
run: |
curl -X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
https://api.github.com/repos/${{ github.repository }}/dispatches \
-d '{"event_type":"benchmark_data_updated"}'