CI #604
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: CI | |
on: | |
schedule: | |
# Check for update every day at 07:11 | |
- cron: '11 7 * * *' | |
# Allows you to run this workflow manually from the Actions tab | |
workflow_dispatch: | |
env: | |
WORKING_BRANCH: ci/${{ github.ref_name }} | |
PR_BRANCH: pr/ci/${{ github.ref_name }} | |
concurrency: | |
# Github Actions does not support ${{ env.WORKING_BRANCH }} as group name... | |
group: ci/${{ github.ref_name }} | |
jobs: | |
prepare: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
path: "bottle-components-repository" | |
ref: ${{ github.ref_name }} | |
fetch-depth: 0 | |
- name: Create or reset ${{ env.WORKING_BRANCH }} | |
working-directory: "bottle-components-repository" | |
shell: bash {0} | |
run: | | |
git config user.email "github-actions[bot]@users.noreply.github.com" | |
git config user.name "github-actions[bot]" | |
pr_already_exists=$(gh pr list --app 'github-actions' --head ${{ env.PR_BRANCH }} --base ${{ github.ref_name }} --state 'open' --json number --jq '.[] | .[]') | |
if ! [ -z "$pr_already_exists" ]; then | |
declare -a BranchArray=( "${{ env.PR_BRANCH }}" "${{ env.WORKING_BRANCH }}" ) | |
status=0 | |
for BRANCH in ${BranchArray[@]}; do | |
git checkout $BRANCH | |
git rebase ${{ github.ref_name }} | |
status=$? | |
if [ $status -eq 0 ]; then | |
git push -f origin $BRANCH | |
else | |
break | |
fi | |
done | |
if [ $status -eq 0 ]; then | |
exit 0 | |
fi | |
fi | |
git reset --hard ${{ github.ref_name }} | |
git checkout -B ${{ env.PR_BRANCH }} | |
git push -f --set-upstream origin ${{ env.PR_BRANCH }} | |
git checkout -B ${{ env.WORKING_BRANCH }} | |
mkdir patch_dir | |
touch patch_dir/.gitkeep | |
git add patch_dir/.gitkeep | |
git commit -m "Add .gitkeep file" | |
git push -f --set-upstream origin ${{ env.WORKING_BRANCH }} | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
pull: | |
needs: prepare | |
strategy: | |
fail-fast: false | |
matrix: | |
components: [ | |
{order: 1 , repo : "doitsujin/dxvk" , project-id: 0 , workflow: "artifacts.yml" , branch: "master", name-prefix: "dxvk-" , name-suffix: "" , version-prefix: "v" , Category: "dxvk" , Sub-category: "" , yaml-file: "14-dxvk.yml" }, | |
{order: 2 , repo : "HansKristian-Work/vkd3d-proton" , project-id: 0 , workflow: "artifacts.yml" , branch: "master", name-prefix: "vkd3d-proton-" , name-suffix: "" , version-prefix: "v" , Category: "vkd3d" , Sub-category: "" , yaml-file: "13-vkd3d-proton.yml" }, | |
{order: 3 , repo : "bottlesdevs/wine" , project-id: 0 , workflow: "" , branch: "soda" , name-prefix: "soda-" , name-suffix: "" , version-prefix: "soda-" , Category: "runners" , Sub-category: "wine" , yaml-file: "3-soda.yml" }, | |
{order: 4 , repo : "bottlesdevs/wine" , project-id: 0 , workflow: "" , branch: "caffe" , name-prefix: "caffe-" , name-suffix: "" , version-prefix: "caffe-" , Category: "runners" , Sub-category: "wine" , yaml-file: "4-caffe.yml" }, | |
{order: 5 , repo : "GloriousEggroll/wine-ge-custom" , project-id: 0 , workflow: "" , branch: "master", name-prefix: "wine-" , name-suffix: "" , version-prefix: "" , Category: "runners" , Sub-category: "wine" , yaml-file: "5-wine-GE-Proton.yml"}, | |
{order: 6 , repo : "GloriousEggroll/proton-ge-custom", project-id: 0 , workflow: "" , branch: "master", name-prefix: "GE-Proton" , name-suffix: "" , version-prefix: "GE-Proton", Category: "runners" , Sub-category: "proton", yaml-file: "10-GE-Proton.yml" }, | |
{order: 7 , repo : "ishitatsuyuki/LatencyFleX" , project-id: 0 , workflow: "artifact.yml" , branch: "master", name-prefix: "latencyflex-" , name-suffix: "" , version-prefix: "" , Category: "latencyflex", Sub-category: "" , yaml-file: "17-latencyflex.yml" }, | |
{order: 8 , repo : "jp7677/dxvk-nvapi" , project-id: 0 , workflow: "artifacts.yml" , branch: "master", name-prefix: "dxvk-nvapi-" , name-suffix: "" , version-prefix: "" , Category: "nvapi" , Sub-category: "" , yaml-file: "16-dxvk-nvapi.yml" }, | |
{order: 9 , repo : "Sporif/dxvk-async" , project-id: 0 , workflow: "" , branch: "master", name-prefix: "dxvk-async-" , name-suffix: "" , version-prefix: "" , Category: "dxvk" , Sub-category: "" , yaml-file: "15-dxvk-async.yml" }, | |
{order: 10, repo : "Kron4ek/Wine-Builds" , project-id: 0 , workflow: "" , branch: "master", name-prefix: "wine-" , name-suffix: "-staging-tkg-amd64", version-prefix: "" , Category: "runners" , Sub-category: "wine" , yaml-file: "11-kron4ek.yml" }, | |
{order: 11, repo : "Kron4ek/Wine-Builds" , project-id: 0 , workflow: "" , branch: "master", name-prefix: "wine-" , name-suffix: "-staging-amd64" , version-prefix: "" , Category: "runners" , Sub-category: "wine" , yaml-file: "11-kron4ek.yml" }, | |
{order: 12, repo : "Kron4ek/Wine-Builds" , project-id: 0 , workflow: "" , branch: "master", name-prefix: "wine-" , name-suffix: "-amd64" , version-prefix: "" , Category: "runners" , Sub-category: "wine" , yaml-file: "11-kron4ek.yml" }, | |
{order: 13, repo : "bottlesdevs/runtime" , project-id: 0 , workflow: "" , branch: "main" , name-prefix: "runtime-" , name-suffix: "" , version-prefix: "" , Category: "runtimes" , Sub-category: "" , yaml-file: "1-runtime.yml" }, | |
{order: 14, repo : "Ph42oN/dxvk-gplasync" , project-id: 43488626, workflow: "" , branch: "main" , name-prefix: "dxvk-gplasync-", name-suffix: "" , version-prefix: "" , Category: "dxvk" , Sub-category: "" , yaml-file: "15-dxvk-async.yml" }, | |
] | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
path: "bottle-components-repository" | |
ref: ${{ env.PR_BRANCH }} | |
- uses: actions/setup-python@v4 | |
with: | |
python-version: '3.x' | |
cache: 'pip' | |
cache-dependency-path: 'bottle-components-repository/input_files/requirements-dev.txt' | |
# Also needs python3-pip, zstd, gawk and gh packages which are pre-installed | |
- run: pip install -r bottle-components-repository/input_files/requirements-dev.txt | |
- name: Check for new release | |
id: check-release | |
shell: bash {0} | |
run: | | |
if [ ${{ matrix.components.project-id }} -ne 0 ]; then | |
gitlab_json=$(curl -s https://gitlab.com/api/v4/projects/${{ matrix.components.project-id }}/releases) | |
latest_release=$(echo -E "$gitlab_json" | jq -r ".[] | select(.tag_name | startswith(\"${{ matrix.components.version-prefix }}\")) | .tag_name" | head -1) | |
else | |
latest_release=$(gh release list -R ${{ matrix.components.repo }} | grep -m1 "${{ matrix.components.version-prefix }}" | awk '{print $(NF-1)}') | |
fi | |
if [ -z "$latest_release" ]; then | |
echo "::error::Cannot find release tag begining by: ${{ matrix.components.version-prefix }}" | |
exit 1 | |
fi | |
asset_name=" " | |
found=false | |
i=-1 | |
until [ -z "$asset_name" ] || [ "$asset_name" = null ] || [ "$found" = true ]; do | |
i=$((i + 1)) | |
if [ ${{ matrix.components.project-id }} -ne 0 ]; then | |
asset_name=$(echo -E "$gitlab_json" | jq -r ".[] | if .tag_name == \"$latest_release\" then . else empty end | .assets | .links | .[$i] | .name") | |
else | |
asset_name=$(gh release view "$latest_release" --json assets -q ".[] | .[$i] | .name" -R ${{ matrix.components.repo }}) | |
fi | |
if [[ "$asset_name" =~ ${{ matrix.components.name-prefix }}.*[0-9]+${{ matrix.components.name-suffix }}\.tar.* ]]; then | |
found=true | |
fi | |
done | |
if [ "$found" = false ]; then | |
echo "::error::Cannot find a corresponding asset name." | |
exit 1 | |
else | |
if [ ${{ matrix.components.project-id }} -ne 0 ]; then | |
timestamp=$(echo -E "$gitlab_json" | jq -r ".[] | if .tag_name == \"$latest_release\" then . else empty end | .created_at") | |
asset_json_raw=$(echo -E "$gitlab_json" | jq -r ".[] | if .tag_name == \"$latest_release\" then . else empty end | .assets | .links | .[$i]") | |
asset_json_raw=$(echo -E "$asset_json_raw" | jq -r ".[\"url\"] = .direct_asset_url") | |
asset_json=$(echo -E "$asset_json_raw" | jq -c ". += {createdAt: \"$timestamp\"}") | |
else | |
asset_json=$(gh release view "$latest_release" --json assets -q ".[] | .[$i]" -R ${{ matrix.components.repo }}) | |
fi | |
echo "asset=$asset_json" >> $GITHUB_OUTPUT | |
echo "version=${latest_release#${{ matrix.components.version-prefix }}}" >> $GITHUB_OUTPUT | |
fi | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- uses: actions/checkout@v4 | |
with: | |
repository: bottlesdevs/tools | |
path: "tools" | |
- name: Define environment variables | |
run: | | |
lowercase_component_name=$(echo "${{ matrix.components.name-prefix }}${{ steps.check-release.outputs.version }}${{ matrix.components.name-suffix }}" | tr "[:upper:]" "[:lower:]") | |
name_prefix="$(echo ${{ matrix.components.name-prefix }} | tr '[:upper:]' '[:lower:]')" | |
echo "NAMEPREFIX=$name_prefix" >> $GITHUB_ENV | |
echo "NAMESUFFIX=$(echo ${{ matrix.components.name-suffix }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV | |
echo "NAME=$lowercase_component_name" >> $GITHUB_ENV | |
echo "CATEGORY=${{ matrix.components.Category }}" >> $GITHUB_ENV | |
echo "SUBCATEGORY=${{ matrix.components.Sub-category }}" >> $GITHUB_ENV | |
echo "CHANNEL=stable" >> $GITHUB_ENV | |
echo "YAML_FILENAME=${{ matrix.components.yaml-file }}" >> $GITHUB_ENV | |
echo "CREATED_AT=${{ fromJSON(steps.check-release.outputs.asset).createdAt }}" >> $GITHUB_ENV | |
echo "UPDATED=false" >> $GITHUB_ENV | |
# Components specific tweaks | |
if [[ "${{ matrix.components.repo }}" == "GloriousEggroll/wine-ge-custom" ]]; then | |
url="${{ fromJSON(steps.check-release.outputs.asset).url }}" | |
name="${url##*/wine-}" | |
name="${name%.tar*}" | |
name="${name%-x86_64}" | |
if [[ "$name" == "lutris-ge-lol-"* ]]; then | |
echo "NAMEPREFIX=lutris-ge-lol-" >> $GITHUB_ENV | |
echo "NAME=$name" >> $GITHUB_ENV | |
fi | |
elif [[ "${{ matrix.components.repo }}" == "Kron4ek/Wine-Builds" ]]; then | |
echo "NAMEPREFIX=kron4ek-$name_prefix" >> $GITHUB_ENV | |
echo "NAME=kron4ek-$lowercase_component_name" >> $GITHUB_ENV | |
fi | |
- name: Update stable input_file entry | |
working-directory: "bottle-components-repository" | |
run: | | |
# This script can set env.UPDATED to true | |
./input_files/update_yml_entries.sh | |
- name: Create release tar archive | |
if: env.UPDATED == 'true' | |
working-directory: "bottle-components-repository" | |
run: | | |
release_archive_url=${{ fromJSON(steps.check-release.outputs.asset).url }} | |
release_archive_name=${{ fromJSON(steps.check-release.outputs.asset).name }} | |
if [[ $release_archive_name == *".tar.zst" ]]; then | |
curl -fsSLO "$release_archive_url" | |
tar --use-compress-program=unzstd -xvf $release_archive_name | |
tar -zcvf "${{ env.NAME }}.tar.gz" "${{ env.NAME }}" | |
echo "UPLOAD_FILE=$(pwd)/${{ env.NAME }}.tar.gz" >> $GITHUB_ENV | |
elif [[ $release_archive_name == "dxvk-nvapi"* ]]; then | |
curl -fsSLO "$release_archive_url" | |
mkdir "${{ env.NAME }}" | |
tar -xvf $release_archive_name --directory "${{ env.NAME }}" | |
tar -zcvf "${{ env.NAME }}.tar.gz" "${{ env.NAME }}" | |
echo "UPLOAD_FILE=$(pwd)/${{ env.NAME }}.tar.gz" >> $GITHUB_ENV | |
fi | |
- name: Check for new artifact | |
id: download-artifact | |
if: matrix.components.workflow != '' && env.UPDATED != 'true' | |
shell: bash {0} | |
run: | | |
run_id=$(gh run list -b ${{ matrix.components.branch }} -w ${{ matrix.components.workflow }} -R ${{ matrix.components.repo }} --json databaseId -q '.[] | .databaseId' --status success -L 1) | |
status=$? | |
if [ $status -ne 0 ]; then | |
echo "::error::Could not get run ID of last successful run." | |
exit 1 | |
fi | |
found_artifact=true | |
gh run download -R ${{ matrix.components.repo }} $run_id -D artifact | |
status=$? | |
if [ $status -ne 0 ]; then | |
echo "::warning::Could not download artifact, probably expired." | |
found_artifact=false | |
else | |
artifact_info=$(gh run view -R ${{ matrix.components.repo }} $run_id --json headSha,createdAt -q '.') | |
echo "artifact_info=$artifact_info" >> $GITHUB_OUTPUT | |
fi | |
echo "found_artifact=$found_artifact" >> $GITHUB_OUTPUT | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Update environment variables | |
if: env.UPDATED != 'true' && steps.download-artifact.outputs.found_artifact == 'true' | |
run: | | |
commit_sha1="${{ fromJSON(steps.download-artifact.outputs.artifact_info).headSha }}" | |
echo "NAME=${{ env.NAME }}-1-${commit_sha1::7}" >> $GITHUB_ENV | |
echo "CHANNEL=unstable" >> $GITHUB_ENV | |
echo "CREATED_AT=${{ fromJSON(steps.download-artifact.outputs.artifact_info).createdAt }}" >> $GITHUB_ENV | |
- name: Update unstable input_file entry | |
if: env.UPDATED != 'true' && steps.download-artifact.outputs.found_artifact == 'true' | |
working-directory: "bottle-components-repository" | |
run: | | |
# This script can set env.UPDATED to true | |
./input_files/update_yml_entries.sh | |
- name: Create artifact tar archive | |
if: env.UPDATED == 'true' && steps.download-artifact.outputs.found_artifact == 'true' | |
working-directory: "bottle-components-repository" | |
run: | | |
folder=$(find "${{ github.workspace }}/artifact" -name "${{ env.NAMEPREFIX }}*") | |
# Components specific tweaks | |
if [[ "${{ env.NAMEPREFIX }}" == "dxvk"* ]]; then | |
rm -rf "$folder/usr" | |
fi | |
mkdir "${{ env.NAME }}" | |
mv "$folder"/* "${{ env.NAME }}" | |
tar -zcvf "${{ env.NAME }}.tar.gz" "${{ env.NAME }}" | |
echo "UPLOAD_FILE=$(pwd)/${{ env.NAME }}.tar.gz" >> $GITHUB_ENV | |
- name: Upload component archive | |
id: upload-component | |
if: env.UPLOAD_FILE != '' | |
working-directory: "bottle-components-repository" | |
shell: bash {0} | |
run: | | |
gh release create "${{ env.NAME }}" ${{ env.UPLOAD_FILE }} -n "" | |
status=$? | |
if [ $status -ne 0 ]; then | |
gh release upload "${{ env.NAME }}" ${{ env.UPLOAD_FILE }} --clobber | |
status=$? | |
if [ $status -ne 0 ]; then | |
echo "::error::Could not upload component." | |
fi | |
fi | |
asset=$(gh release view "${{ env.NAME }}" --json assets -q ".[] | .[0]") | |
echo "asset=$asset" >> $GITHUB_OUTPUT | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name : Generate appropriate YAML file | |
if: env.UPDATED == 'true' | |
working-directory: "bottle-components-repository" | |
run: | | |
repo=${{ matrix.components.repo }} | |
name=${{ env.NAME }} | |
if [ "${{ env.UPLOAD_FILE }}" != "" ]; then | |
url="${{ steps.upload-component.outputs.asset && fromJSON(steps.upload-component.outputs.asset).url }}" | |
path="${{ env.UPLOAD_FILE }}" | |
else | |
url="${{ fromJSON(steps.check-release.outputs.asset).url }}" | |
fi | |
python "${{ github.workspace }}/tools/MaintainersHelpers/component-generator.py" "components" "CI" "$name" "${repo%/*}" "${{ env.CHANNEL }}" "$url" $path | |
# Components specific tweaks | |
if [[ "$repo" == "GloriousEggroll"* ]]; then | |
source="${url##*/}" | |
source="${source#wine-}" | |
source="${source%.tar*}" | |
source="${source%-x86_64}" | |
echo "Post:" >> "$name.yml" | |
echo -e "- action: rename" >> "$name.yml" | |
echo -e " source: $source" >> "$name.yml" | |
echo -e " dest: $name" >> "$name.yml" | |
elif [[ "$repo" == "Kron4ek/Wine-Builds" ]]; then | |
echo "Post:" >> "$name.yml" | |
echo -e "- action: rename" >> "$name.yml" | |
echo -e " source: ${name#kron4ek-}" >> "$name.yml" | |
echo -e " dest: $name" >> "$name.yml" | |
fi | |
mv "$name.yml" "${{ env.CATEGORY }}/${{ env.SUBCATEGORY }}" | |
- name : Commit changes | |
if: env.UPDATED == 'true' | |
working-directory: "bottle-components-repository" | |
timeout-minutes: 10 | |
shell: bash {0} | |
run: | | |
git config user.email "github-actions[bot]@users.noreply.github.com" | |
git config user.name "github-actions[bot]" | |
git add "${{ env.CATEGORY }}/${{ env.SUBCATEGORY }}/${{ env.NAME }}.yml" "input_files/${{ env.YAML_FILENAME }}" | |
git commit -m "Add ${{ env.NAME }}" | |
file_name="$(date -d "${{ github.event.created_at }}" +%s)-${{ matrix.components.order }}-${{ env.NAME }}.patch" | |
git diff HEAD~1 HEAD > "$file_name" | |
git fetch origin ${{ env.WORKING_BRANCH }}:${{ env.WORKING_BRANCH }} | |
git switch ${{ env.WORKING_BRANCH }} | |
git branch --set-upstream-to=origin/${{ env.WORKING_BRANCH }} ${{ env.WORKING_BRANCH }} | |
mv "$file_name" patch_dir | |
git add patch_dir/*.patch | |
git pull | |
git commit -m "Add ${{ env.NAME }}" | |
git push | |
success=$? | |
until [ $success -eq 0 ]; do | |
git pull --rebase; | |
git push | |
success=$? | |
done | |
finish: | |
needs: [prepare, pull] | |
if: always() && needs.prepare.result == 'success' | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
path: "bottle-components-repository" | |
ref: ${{ env.WORKING_BRANCH }} | |
fetch-depth: 0 | |
- name: Generate index.yml | |
working-directory: "bottle-components-repository" | |
shell: bash {0} | |
run: | | |
git checkout ${{ github.ref_name }} | |
git config user.email "github-actions[bot]@users.noreply.github.com" | |
git config user.name "github-actions[bot]" | |
git merge ${{ env.WORKING_BRANCH }} --no-commit --no-ff | |
git reset | |
readarray -d '' entries < <(printf '%s\0' patch_dir/*.patch | sort -zV) | |
for entry in "${entries[@]}"; do | |
patch -p1 --fuzz 5 < "$entry" | |
git add -- . ':!patch_dir' ':!**.orig' | |
entry=${entry#patch_dir/*-[0-9]*-} | |
git commit -a -m "Add component ${entry%\.patch}" | |
done | |
./generate_index.sh | |
git add index.yml | |
git commit -m "Generate index.yml" || true | |
- name: Create Pull Request | |
id: cpr | |
working-directory: "bottle-components-repository" | |
shell: bash {0} | |
run: | | |
git checkout -B ${{ env.PR_BRANCH }} | |
git push -f --set-upstream origin ${{ env.PR_BRANCH }} | |
gh_output=$(gh pr create --title "Update available :tada:" --body "One or more components have been updated!" --head ${{ env.PR_BRANCH }} --base ${{ github.ref_name }}) | |
echo "PR_CREATED=$([ $? -eq 0 ] && echo true || echo false)" >> $GITHUB_OUTPUT | |
pr_number=$($gh_output | tail -n1) | |
echo "PR_NUMBER=${pr_number#https://github.com/${{ github.repository }}/pull/}" >> $GITHUB_OUTPUT | |
env: | |
# PAT is not necessary unless auto-merge is used | |
# GH_TOKEN: ${{secrets.PAT}} | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Enable Pull Request Automerge | |
if: false | |
# if: steps.cpr.outputs.PR_CREATED == 'true' | |
run: gh pr merge --merge --auto "${{ steps.cpr.outputs.PR_NUMBER }}" | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Auto approve | |
if: false | |
# if: steps.cpr.outputs.PR_CREATED == 'true' | |
run: gh pr review --approve "${{ steps.cpr.outputs.PR_NUMBER }}" | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |