Skip to content

Commit

Permalink
Add various simplifications and more robust GitHub actions for the ch…
Browse files Browse the repository at this point in the history
…eck-in test (#225)

Minor GitHub action changes. The biggest one is that we have verified that the Gradle caches work between steps, branches and jobs, so nothing building close in time cannot overwrite the GitHub workflow caches for another commit.

We also make sure that all installDist/manualTest verification for the test platforms is finished before trying to publish a snapshot artifact. This is to make sure that even if we run on the publishing platform (ubuntu-latest), and windows fails, we do not publish anything that may be a windows-breaker.

This is all good prep work for the jreleaser configuration which will accept an uploaded build artifact blob consisting of the installWithLaunchersDist destination directories after uploadArtifact.

We have also added various cleaners that are meant to run either manually dispatched, and on a cron schedule, so that we keep the number of published snapshots low, with only the ~10 latest ones for the same version. Furthermore we may want to delete old caches for old runs, as well as workflow results, when they cease to be relevant.
  • Loading branch information
lagergren authored May 13, 2024
1 parent 4ef667b commit 163f3fd
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 22 deletions.
115 changes: 115 additions & 0 deletions .github/workflows/cleaners.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@

#
# This is a workflow that is meant to keep our temporary data in check on the server side:
#
# Things we want to make sure stay within bounds are:
#
# * GitHub Action caches, especially for Java distribution and Gradle.
#
# * Snapshot publications. GitHub handles SNAPSHOTS in a non standard way, so it's not possible to just
# enumerate all versions of a SNAPSHOT package, which of course is wrong, according to the Maven
# specification. But since every new commit to master will publish a new platform release, it quickly
# gets uwieldy to keep all those around. We should at most retain maybe the last ~10 commits' worth
# of snapshot publications, or something like that.
#
# * Finished workflows (at least those that have been successful) after a certain number of days.
# Now we just fill up the disk until we hit the GitHub free quota, which is unnecessary, and
# possibly a security hazard if some zero day exploit thing appears, and we happen to have some
# finished workflow that we have forgotten about that printed secrets to the console or something.
#

name: XDK GitHub Actions Cleaner
on:
#
# Set up a periodic cron schedule for this task to make sure cache build-up is curbed.
# We also have a workflow_dispatch mechanism, so that the job can easily be triggered manually from
# the GitHub CLI command "gh", and through the GUI for the GitHub Actions workflow on github.com.
#
# The cron syntax is "minute (0-59), hour (0-23), day (1-31), month (1-12), day of week (0-6)
# For example: "0 13 * * 1" means "every Monday at 1PM UTC (9AM EST, 2PM CEST)"
#
# There is also an "every X" syntax for intervals.
# For example: "*/10 * * * *" means "do something every 10 minutes")
#
# We do the cache cleanup once a week, at midnight UTC. We may want to adjust later.
#

# TODO: Enable as soon as we have a test environment after first merge.
#schedule:
# - cron: "0 0 * * 1"

#
# Allow manual dispatch of this cleanup job from GitHub website under the XVM repository
# Actions tab, as well as from the GitHub CLI and/or the REST API.
#
workflow_dispatch:
dry_run:
description: 'Dry run the cache and workflow cleaner'
required: false
default: false

env:
BOT_TOKEN: ${{ secrets.ORG_XTCLANG_DISCORD_BOT_TOKEN }}
BOT_CHANNEL_ID: ${{ vars.ORG_XTCLANG_DISCORD_GITHUB_CHANNEL_ID }}
# TODO: To get workflow dispatch to work we need to merge the branch into master. Hence, it goes it
# with dry run only as its configuration
DRY_RUN: true # ${{ github.event.inputs.dry_run || false }}
# ACTIONS_RUNNER_DEBUG: true
# ACTIONS_STEP_DEBUG: true

jobs:
clean-workflows:
name: Delete older workflows
runs-on: ubuntu-latest
permissions:
actions: write
contents: read
steps:
- name: Delete old workflow runs
if: ${{ false }}
uses: Mattraks/delete-workflow-runs@v2
with:
token: ${{ github.token }}
repository: ${{ github.repository }}
retain_days: 30
keep_minimum_runs: 6
dry_run: ${{ env.DRY_RUN }}

clean-snapshots:
name: Delete old Maven snapshot packages/publications
runs-on: ubuntu-latest
steps:
- name: Delete old XDK and XTC Plugin Maven snapshot packages
if: ${{ false }}
uses: smartsquaregmbh/[email protected]
with:
organization: 'xtclang'
type: 'maven'
repository: 'xvm'
version-pattern: '.*-SNAPSHOT$'
names: |
org.xtclang.xtc-plugin.org.xtclang.xtc-plugin.gradle.plugin
org.xtclang.xdk
org.xtclang.xtc-plugin
dry_run: ${{ env.DRY_RUN }}

clean-caches:
name: Delete all caches
runs-on: ubuntu-latest
env:
cron_trigger: "${{ github.event_name == 'schedule' && 'true' || 'false' }}"
steps:
- name: Setup cleaner
if: ${{ false }}
shell: bash
run: |
echo "Starting GitHub action cleaner for repository."
echo " Reason : dispatch trigger event: ${{ github.event_name }}."
echo " Dry run : run: ${{ env.cron_trigger }}."
- name: List and/or clean all GitHub action caches
uses: easimon/wipe-cache@main
with:
# TODO: Temporarily disable the cache deletion based on cron schedule, until we have verified it works manually
dry-run: ${{ env.DRY_RUN }}
github-token: ${{ github.token }}
93 changes: 73 additions & 20 deletions .github/workflows/xvm-verify-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
# 2) Cleans Gradle and other build caches, maybe one every 24 h
# 3) Cleans ...
#

# Check if "pull-request" makes it possible to add a branch protection status check requirement on master.
# gh auth switch --hostname enterprise.internal --user monalisa (switch auth)
name: XVM Verification and Package Updates

on:
push:
Expand All @@ -27,6 +27,7 @@ on:
env:
# TODO: Default should be disabled; we only want to be bothered by tagging and publishing for the master branch.
always_publish_snapshot: false
enable_gradle_home_cache_cleanup: true

# Add manual tests as an included build to the composite build configuration, and also build them.
ORG_GRADLE_PROJECT_includeBuildManualTests: true
Expand All @@ -45,7 +46,7 @@ env:
MAVEN_CENTRAL_USERNAME: ${{ secrets.ORG_XTCLANG_MAVEN_CENTRAL_USERNAME }}
MAVEN_CENTRAL_PASSWORD: ${{ secrets.ORG_XTCLANG_MAVEN_CENTRAL_PASSWORD }}

gradle_options: "-Dorg.gradle.jvmargs=-Xmx8G -Dorg.gradle.caching.debug=false -Dorg.gradle.vfs.verbose=false --stacktrace --warning-mode=all --console=plain --profile ${{ inputs.extra_gradle_options }}"
gradle_options: "-Dorg.gradle.jvmargs=-Xmx8G -Dorg.gradle.caching.debug=false -Dorg.gradle.vfs.verbose=false --stacktrace --warning-mode=all --console=plain ${{ inputs.extra_gradle_options }}"

# Optional flags to skip manual tests, or at least some of them.
skip_manual_tests: ${{ github.event.inputs.skip_manual_tests || 'false' }}
Expand All @@ -54,7 +55,7 @@ env:
# Build environment and build workflow debug flags.
# ACTIONS_RUNNER_DEBUG: true
# ACTIONS_STEP_DEBUG: true
# GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true

# Concurrency settings: group by workflow and ref, cancel intermediate builds, but only if it's a pull request build.
concurrency:
Expand All @@ -71,27 +72,34 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4
- name: Fetch Sources
uses: actions/checkout@v4
with:
show-progress: true

- uses: actions/setup-java@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: temurin
distribution: zulu
java-version: 21

- uses: gradle/actions/setup-gradle@v3
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
gradle-home-cache-cleanup: ${{ env.enable_gradle_home_cache_cleanup }}
cache-disabled: ${{ github.ref == 'refs/heads/master' }}
cache-read-only: false

- uses: gradle/actions/wrapper-validation@v3
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v3

- name: Dump environment info
shell: bash
run: |
echo "Branch (github.ref) : ${{ github.ref }}"
echo "Runner OS : ${{ runner.os }}"
echo "Java system properties :"
echo "*** Branch (github.ref) : ${{ github.ref }}"
echo "*** Commit (github.sha) : ${{ github.sha }}"
echo "*** Runner OS : ${{ runner.os }}"
echo "*** Java system properties :"
java -XshowSettings:properties --version
- name: Build the XDK and create a distribution layout
Expand All @@ -109,12 +117,18 @@ jobs:
xec_path=$(find xdk/build/install/ -name xec)
echo "Location of native launcher (xcc): $xcc_path"
echo "Location of native launcher (xec): $xec_path"
echo ">>> Testing native launchers, verifying their binary format and that they run on this platform..."
file $xcc_path
file $xec_path
$xcc_path --version
$xec_path --version
echo "<<< Native launchers work."
echo "*** Testing native launchers, verifying their binary format and that they run on this platform..."
xcc_file=$(file $xcc_path)
xec_file=$(file $xec_path)
xcc_version=$($xcc_path --version)
xec_version=$($xec_path --version)
echo " xcc:"
echo " file : $xcc_file"
echo " version: $xcc_version"
echo " xec:"
echo " file : $xec_file"
echo " version: $xec_version"
echo "*** Native launchers work."
- name: Default manualTest tasks
if: ${{ env.skip_manual_tests != 'true' }}
Expand All @@ -133,8 +147,47 @@ jobs:
run: |
./gradlew ${{ env.gradle_options }} manualTests:runParallel
- name: Publish to GitHub packages iff snapshot + non-redundant build platform + branch is master
if: ${{ ((env.always_publish_snapshot == 'true') || (github.ref == 'refs/heads/master')) && (runner.os == 'Linux') }}
publish-snapshot:
name: Publish to GitHub packages iff snapshot + non-redundant build platform + branch is master
needs: build-verify
runs-on: ubuntu-latest
#if: ${{ (github.ref == 'refs/heads/master') }}
steps:
- name: Maximize Build Space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
large-packages: false

# Check out current repository
- name: Fetch Sources
uses: actions/checkout@v4

# Set up Java environment for the next steps
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: zulu
java-version: 21

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
gradle-home-cache-cleanup: ${{ env.enable_gradle_home_cache_cleanup }}
cache-disabled: ${{ github.ref == 'refs/heads/master' }}
cache-read-only: false

- name: Dump environment info
shell: bash
run: |
echo "*** Branch (github.ref) : ${{ github.ref }}"
echo "*** Commit (github.sha) : ${{ github.sha }}"
echo "*** Runner OS : ${{ runner.os }}"
echo "*** Java system properties :"
java -XshowSettings:properties --version
- name: Create or Update Snapshot (if pushed to 'master', or env.always_publish_snapshot is true)
if: ${{ (env.always_publish_snapshot == 'true') || (github.ref == 'refs/heads/master') }}
shell: bash
run: |
./gradlew ${{ env.gradle_options }} xdk:ensureTags -PsnapshotOnly=true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public FileCollection filesFromConfigs(final boolean shouldBeResolved, final Lis
logger.info("{} Scanning file collection: filesFrom: {} {}, files: {}", prefix, name, config.getState(), files.getFiles());
fc = fc.plus(files);
}
fc.getAsFileTree().forEach(it -> logger.info("{} Resolved fileTree '{}'", prefix, it.getAbsolutePath()));
fc.getAsFileTree().forEach(it -> logger.debug("{} Resolved fileTree '{}'", prefix, it.getAbsolutePath()));
return fc;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static org.xtclang.plugin.XtcPluginConstants.XTC_LANGUAGE_NAME;
import static org.xtclang.plugin.XtcPluginUtils.FileUtils.isValidXtcModule;
import static org.xtclang.plugin.XtcPluginUtils.argumentArrayToList;
import static org.xtclang.plugin.XtcPluginUtils.capitalize;
import static org.xtclang.plugin.XtcPluginUtils.singleArgumentIterableProvider;

import java.io.File;
Expand Down Expand Up @@ -271,7 +272,7 @@ protected List<File> resolveFullModulePath() {

for (final var sourceSet : getDependentSourceSets()) {
final Set<File> sourceSetOutput = resolveDirectories(XtcProjectDelegate.getXtcSourceSetOutputDirectory(project, sourceSet));
map.put(XTC_LANGUAGE_NAME + sourceSet.getName(), sourceSetOutput);
map.put(XTC_LANGUAGE_NAME + capitalize(sourceSet.getName()), sourceSetOutput);
}

logger.info("{} Compilation/runtime full module path resolved as: ", prefix());
Expand Down

0 comments on commit 163f3fd

Please sign in to comment.