Reverse-Engineer Case Studies #376
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"}' |