From f04d07575f8ec18298b1e322ce3c640c4e02f541 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 27 Aug 2024 17:06:23 +0200 Subject: [PATCH] WIP testing build limiting --- .github/matrix.php | 114 ++++++++++++++++++++++++++++++++++++ .github/workflows/limit.yml | 54 +++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100755 .github/matrix.php create mode 100644 .github/workflows/limit.yml diff --git a/.github/matrix.php b/.github/matrix.php new file mode 100755 index 0000000..f20170b --- /dev/null +++ b/.github/matrix.php @@ -0,0 +1,114 @@ + [ + 'method' => "GET", + 'header' => join("\r\n", [ + "Accept: application/vnd.github.v3+json", + "User-Agent: PHP" + ]) + ] + ]; + $context = stream_context_create($opts); + + $data = file_get_contents('https://api.github.com/repos/dokuwiki/dokuwiki/commits/' . $branch, false, $context); + $json = json_decode($data, true); + return $json['sha']; +} + +/** + * Get the image id of a given PHP image tag + * + * @param string $tag + * @return string + */ +function getImageId($tag) +{ + $repo = 'library/php'; + $data = file_get_contents('https://auth.docker.io/token?service=registry.docker.io&scope=repository:' . $repo . ':pull'); + $token = json_decode($data, true)['token']; + + + $opts = [ + 'http' => [ + 'method' => "GET", + 'header' => join("\r\n", [ + "Authorization: Bearer $token", + "Accept: application/vnd.docker.distribution.manifest.v2+json", + ]) + ] + ]; + $context = stream_context_create($opts); + + $data = file_get_contents('https://index.docker.io/v2/' . $repo . '/manifests/' . $tag, false, $context); + $json = json_decode($data, true); + return $json['config']['digest']; +} + +/** + * Get the image tag used in the current Dockerfile + * + * @return string + */ +function getImageTag() +{ + $df = file_get_contents('Dockerfile'); + preg_match('/FROM php:(?\S*)/', $df, $matches); + return $matches['tag']; +} + + +$result = []; +$self = $_ENV['GITHUB_SHA'] ?? 'unknown'; +$upstreamTag = getImageTag(); +$image = getImageId($upstreamTag); + +foreach (getVersions() as $release => $info) { + $branch = $release === 'oldstable' ? 'old-stable' : $release; + $commit = getLastCommit($branch); + $ident = join('-', [$release, $commit, $image, $self]); + $cache = '.github/matrix.cache/' . $release; + + fwrite(STDERR, "Ident: $ident\n"); + $last = @file_get_contents($cache); + if ($last === $ident) { + // this combination has been built before + fwrite(STDERR, "No change. Skipping $release\n"); + continue; + } + + // this branch needs to be built + $result[] = [ + 'version' => $info['version'], + 'date' => $info['date'], + 'name' => $info['name'], + 'type' => $release, + ]; + // update the cache + if(!is_dir('.github/matrix.cache')) { + mkdir('.github/matrix.cache'); + } + file_put_contents($cache, $ident); +} + +// output the result +echo json_encode(['release' => $result], JSON_PRETTY_PRINT); diff --git a/.github/workflows/limit.yml b/.github/workflows/limit.yml new file mode 100644 index 0000000..2823f9e --- /dev/null +++ b/.github/workflows/limit.yml @@ -0,0 +1,54 @@ +name: Test Limit +on: + workflow_dispatch: + schedule: + - cron: "23 0 * * *" + push: + branches: + - limit + +jobs: + buildmatrix: + name: Create Build Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + - name: Cache Setup + id: cache + uses: actions/cache@v4 + with: + path: .github/matrix.cache/ + key: ${{ runner.os }}-matrix-${{ hashFiles('.github/matrix.php') }} + - name: Set up matrix + id: set-matrix + run: | + php .github/matrix.php >> $GITHUB_OUTPUT + + build: + needs: buildmatrix + name: Build Docker Image for ${{ matrix.release.type }} + runs-on: ubuntu-latest + strategy: + matrix: ${{fromJson(needs.buildmatrix.outputs.matrix)}} + steps: + - + name: Checkout + uses: actions/checkout@v4 + + + workflow-keepalive: + if: github.event_name == 'schedule' + runs-on: ubuntu-latest + permissions: + actions: write + steps: + - uses: liskin/gh-workflow-keepalive@v1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}