diff --git a/.github/testing-issue-template.md b/.github/testing-issue-template.md deleted file mode 100644 index 87273cb..0000000 --- a/.github/testing-issue-template.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Call for testing `{{ env.SNAP_NAME }}` -labels: testing ---- - -A new version ({{ env.version }}) of `{{ env.SNAP_NAME }}` was just pushed to the `{{ env.CHANNEL }}` channel [in the snap store](https://snapcraft.io/{{ env.SNAP_NAME }}). The following revisions are available. - -{{ env.table }} - -## Automated screenshots - -The snap will be installed in a VM automatically; screenshots will be posted as a comment on this issue shortly. - -## How to test it manually - -1. Stop the application if it was already running -1. Upgrade to this version by running - - ```shell - snap refresh {{ env.SNAP_NAME }} --{{ env.CHANNEL }} - ``` - -1. Start the app and test it out. -1. Finally, add a comment below explaining whether this app is working, and **include the output of the following command**. - - ```shell - snap version; lscpu | grep Architecture; snap info {{ env.SNAP_NAME }} | grep installed - ``` - -## How to release it - -Maintainers can promote this to stable by commenting `/promote [,] stable [done]`. - -> For example -> -> - To promote a single revision, run `/promote stable` -> - To promote multiple revisions, run `/promote , stable` -> - To promote a revision and close the issue, run `/promote , stable done` - -You can promote all revisions that were just built with: - -``` -/promote {{ env.revisions }} stable done -``` diff --git a/.github/vmctl b/.github/vmctl deleted file mode 100755 index 0fd87b0..0000000 --- a/.github/vmctl +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Default VM attributes - tuned for Github Actions runners by default -VM_NAME="${VM_NAME:-test-vm}" -VM_SERIES="${VM_SERIES:-22.04}" -VM_CPUS="${VM_CPUS:=1}" -VM_MEM_GIB="${VM_MEM_GIB:=6}" -VM_DISK_GIB="${VM_DISK_GIB:=12}" - -build_runner_script() { - vmctl_runner="$(mktemp)" - chmod +x "$vmctl_runner" - cat <<-EOF > "$vmctl_runner" -#!/usr/bin/env bash - -export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus -export WAYLAND_DISPLAY=wayland-0 -export DISPLAY=:0.0 -export HOME=/home/ubuntu - -exec "\$@" -EOF - - echo "$vmctl_runner" -} - -# If we're on a Github Actions Runner, enable KVM. -enable_kvm_gha() { - if [[ -x "${GITHUB_ACTIONS:-}" ]]; then - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm - fi -} - -# Starts a desktop VM and waits for the agent to be running inside. -prepare_vm() { - # Start the VM - lxc launch "images:ubuntu/${VM_SERIES}/desktop" "${VM_NAME}" --vm \ - -c limits.cpu="${VM_CPUS}" -c limits.memory="${VM_MEM_GIB}GiB" -d root,size="${VM_DISK_GIB}GiB" - - # Wait for the VM agent to be running - while ! lxc exec test-vm -- cat /etc/hostname &>/dev/null; do - sleep 2 - done - - # Push script runner into the VM - lxc file push "$(build_runner_script)" test-vm/bin/vmctl-runner - lxc exec test-vm -- chmod 755 /bin/vmctl-runner - - # Install gnome-screenshot - lxc exec test-vm -- apt-get update - lxc exec test-vm -- apt-get install -y gnome-screenshot - - # Kill the gnome initial setup wizard - pid="$(lxc exec test-vm -- pidof gnome-initial-setup)" - lxc exec test-vm -- kill -9 "$pid" -} - -# Exec a command in the VM using the wrapper. -exec_in_vm() { - lxc exec test-vm -- sudo -u ubuntu bash -c "/bin/vmctl-runner $@" -} - -# Takes a screenshot of the full screen and pulls the file back from the VM to a file -# named "screenshot-screen.png", and uploads to imgur, returning the URL -screenshot_full() { - # Take a screenshot of the whole screen in the VM - exec_in_vm "gnome-screenshot -f /home/ubuntu/screen.png" - # Pull the screenshot back to the host - lxc file pull test-vm/home/ubuntu/screen.png screenshot-screen.png -} - -# Takes a screenshot of the active window and pulls the file back from the VM to a file -# named "screenshot-window.png", and uploads to imgur, returning the URL -screenshot_window() { - # Take a screenshot of the active window in the VM - exec_in_vm "gnome-screenshot -w -f /home/ubuntu/window.png" - # Pull the screenshot back to the host - lxc file pull test-vm/home/ubuntu/window.png screenshot-window.png -} - -# Print the usage statement and exit the program -usage() { - echo "Usage: vmctl [prepare | push-snap | exec | screenshot-full | screenshot-window"] - exit 1 -} - -# Parse the subcommand and exit if empty, printing the usage -command="${1:-}"; shift -if [[ -z "$command" ]]; then - usage -fi - -case "$command" in - "prepare") - enable_kvm_gha - prepare_vm - ;; - "exec") - exec_in_vm "$@" - ;; - "screenshot-full") - screenshot_full - ;; - "screenshot-window") - screenshot_window - ;; - *) - usage - ;; -esac diff --git a/.github/workflows/promote-to-stable.yml b/.github/workflows/promote-to-stable.yml new file mode 100644 index 0000000..f38b063 --- /dev/null +++ b/.github/workflows/promote-to-stable.yml @@ -0,0 +1,25 @@ +name: Promote + +on: + issue_comment: + types: + - created + +permissions: + issues: write + +jobs: + promote: + name: โฌ†๏ธ Promote to stable + environment: "Candidate Branch" + runs-on: ubuntu-latest + if: | + ( !github.event.issue.pull_request ) + && contains(github.event.comment.body, '/promote ') + && contains(github.event.*.labels.*.name, 'testing') + steps: + - name: โฌ†๏ธ Promote to stable + uses: snapcrafters/ci/promote-to-stable@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + store-token: ${{ secrets.SNAP_STORE_STABLE }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..3fede67 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,17 @@ +name: Pull Request + +on: + pull_request: + branches: [ "**" ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: ๐Ÿงช Build snap on amd64 + runs-on: ubuntu-latest + steps: + - name: ๐Ÿงช Build snap on amd64 + uses: snapcrafters/ci/test-snap-build@main diff --git a/.github/workflows/release-to-candidate.yaml b/.github/workflows/release-to-candidate.yaml new file mode 100644 index 0000000..3aaba36 --- /dev/null +++ b/.github/workflows/release-to-candidate.yaml @@ -0,0 +1,71 @@ +name: Release + +on: + # Run the workflow each time new commits are pushed to the candidate branch. + push: + branches: [ "candidate" ] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + issues: write + +jobs: + get-architectures: + name: ๐Ÿ–ฅ Get snap architectures + runs-on: ubuntu-latest + outputs: + architectures: ${{ steps.get-architectures.outputs.architectures }} + architectures-list: ${{ steps.get-architectures.outputs.architectures-list }} + steps: + - name: ๐Ÿ–ฅ Get snap architectures + id: get-architectures + uses: snapcrafters/ci/get-architectures@main + + release: + name: ๐Ÿšข Release to latest/candidate + needs: get-architectures + runs-on: ubuntu-latest + environment: "Candidate Branch" + strategy: + matrix: + architecture: ${{ fromJSON(needs.get-architectures.outputs.architectures-list) }} + steps: + - name: ๐Ÿšข Release to latest/candidate + uses: snapcrafters/ci/release-to-candidate@main + with: + architecture: ${{ matrix.architecture }} + launchpad-token: ${{ secrets.LP_BUILD_SECRET }} + store-token: ${{ secrets.SNAP_STORE_CANDIDATE }} + + call-for-testing: + name: ๐Ÿ“ฃ Create call for testing + needs: [release, get-architectures] + environment: "Candidate Branch" + runs-on: ubuntu-latest + outputs: + issue-number: ${{ steps.issue.outputs.issue-number }} + steps: + - name: ๐Ÿ“ฃ Create call for testing + id: issue + uses: snapcrafters/ci/call-for-testing@main + with: + architectures: ${{ needs.get-architectures.outputs.architectures }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + screenshots: + name: ๐Ÿ“ธ Gather screenshots + needs: call-for-testing + environment: "Candidate Branch" + runs-on: ubuntu-latest + steps: + - name: ๐Ÿ“ธ Gather screenshots + uses: snapcrafters/ci/get-screenshots@main + with: + issue-number: ${{ needs.call-for-testing.outputs.issue-number }} + github-token: ${{ secrets.GITHUB_TOKEN }} + screenshots-token: ${{ secrets.SNAPCRAFTERS_BOT_COMMIT }} diff --git a/.github/workflows/snap-store-promote-to-stable.yml b/.github/workflows/snap-store-promote-to-stable.yml deleted file mode 100644 index d015b4b..0000000 --- a/.github/workflows/snap-store-promote-to-stable.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: ๐Ÿ“ฆ Promote to stable - -on: - issue_comment: - types: - - created - -permissions: - issues: write - -env: - SNAP_NAME: ${{ github.event.repository.name }} - -jobs: - promote: - environment: "Candidate Branch" - runs-on: ubuntu-latest - if: | - ( !github.event.issue.pull_request ) - && contains(github.event.comment.body, '/promote ') - && contains(github.event.*.labels.*.name, 'testing') - steps: - - id: command - uses: xt0rted/slash-command-action@v2 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - command: promote - reaction: "true" - reaction-type: "eyes" - allow-edits: "false" - permission-level: write - - id: promote - env: - SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_STORE_STABLE }} - run: | - echo "The command was '${{ steps.command.outputs.command-name }}' with arguments '${{ steps.command.outputs.command-arguments }}'" - arguments=(${{ steps.command.outputs.command-arguments }}) - revision=${arguments[0]} - channel=${arguments[1]} - done=${arguments[2]} - - # Validation checks - re='^[0-9]+([,][0-9]+)*$' - if [[ ! "$revision" =~ $re ]]; then - echo "revision must be a number or a comma seperated list of numbers, not '$revision'!" - exit 1 - fi - if [[ "$channel" != "stable" ]]; then - echo "I can only promote to stable, not '$channel'!" - exit 1 - fi - if [[ -n "$done" && "$done" != "done" ]]; then - echo "The third argument should be 'done' or empty" - exit 1 - fi - - # Install Snapcraft - sudo snap install --classic snapcraft - sudo chown root:root / - - # Iterate over each specified revision and release - revs=$(echo $revision | tr "," "\n") - released_revs=() - - for r in $revs; do - snapcraft release $SNAP_NAME "$r" "$channel" - released_revs+=("$r") - done - - echo "revisions=${released_revs[@]}" >> $GITHUB_OUTPUT - echo "channel=$channel" >> $GITHUB_OUTPUT - echo "done=$done" >> $GITHUB_OUTPUT - - uses: actions/github-script@v7 - with: - script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: 'The following revisions were released to the `${{ steps.promote.outputs.channel }}` channel: `${{ steps.promote.outputs.revisions }}`' - }) - if ("${{ steps.promote.outputs.done }}" === "done") { - github.rest.issues.update({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - state: 'closed' - }) - } diff --git a/.github/workflows/snap-store-publish-to-candidate.yml b/.github/workflows/snap-store-publish-to-candidate.yml deleted file mode 100644 index b174098..0000000 --- a/.github/workflows/snap-store-publish-to-candidate.yml +++ /dev/null @@ -1,249 +0,0 @@ -name: ๐Ÿ“ฆ Publish to candidate - -on: - # Run the workflow each time new commits are pushed to the candidate branch. - push: - branches: [ "candidate" ] - # Allow the workflow to be started manually from the Actions tab. - workflow_dispatch: - # Allow the workflow to be started by another workflow. - workflow_call: - secrets: - SNAP_STORE_CANDIDATE: - required: true - LP_BUILD_SECRET: - required: true - SNAPCRAFTERS_BOT_COMMIT: - required: true - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -# Permissions for GITHUB_TOKEN -permissions: - contents: read - issues: write - -env: - # Use the name of the repo as the name of the snap - SNAP_NAME: ${{ github.event.repository.name }} - # Hardcoded git branch and Snap Store channel channel - CHANNEL: 'candidate' - -jobs: - get_archs: - name: Compute architectures - runs-on: ubuntu-latest - outputs: - archs: ${{ steps.archs.outputs.archs }} - steps: - - name: Checkout the source - uses: actions/checkout@v4 - with: - ref: ${{ env.CHANNEL }} - - - name: Compute architectures - id: archs - run: | - # Handle the case where architectures is a simple list of strings - archs="$(cat snap/snapcraft.yaml | yq -I=0 -o=json '[.architectures[]]')" - - # Handle the case where architectures is a list of objects - if echo "$archs" | grep -q "build-on"; then - archs="$(cat snap/snapcraft.yaml | yq -I=0 -o=json '[.architectures[]."build-on"]')" - fi - - echo "archs=$archs" >> "$GITHUB_OUTPUT" - - build: - name: "Build & publish" - environment: "Candidate Branch" - runs-on: ubuntu-latest - needs: [get_archs] - strategy: - matrix: - # Parse the list of architectures from the output we created above (one job per arch) - architecture: ${{ fromJSON(needs.get_archs.outputs.archs) }} - outputs: - version: ${{ steps.build.outputs.version }} - steps: - - name: Checkout the source - uses: actions/checkout@v4 - with: - ref: ${{ env.CHANNEL }} - - - name: Setup snapcraft - env: - LP_BUILD_SECRET: ${{ secrets.LP_BUILD_SECRET }} - run: | - sudo snap install snapcraft --classic - - # Setup Launchpad credentials - mkdir -p ~/.local/share/snapcraft/provider/launchpad - echo "$LP_BUILD_SECRET" > ~/.local/share/snapcraft/provider/launchpad/credentials - git config --global user.email "github-actions@github.com" - git config --global user.name "Github Actions" - - # Install moreutils so we have access to sponge - sudo apt-get update; sudo apt-get install -y moreutils - - - name: Remote build the snap - id: build - env: - ARCHITECTURE: ${{ matrix.architecture }} - run : | - # Remove the architecture definition from the snapcraft.yaml due to: - # https://bugs.launchpad.net/snapcraft/+bug/1885150 - cat snap/snapcraft.yaml | yq 'del(.architectures)' | sponge snap/snapcraft.yaml - - snapcraft remote-build --launchpad-accept-public-upload --build-for=${ARCHITECTURE} - - version="$(cat snap/snapcraft.yaml | yq -r '.version')" - echo "version=${version}" >> "$GITHUB_OUTPUT" - echo "snap=${{ env.SNAP_NAME }}_${version}_${ARCHITECTURE}.snap" >> "$GITHUB_OUTPUT" - - - name: Review the built snap - uses: diddlesnaps/snapcraft-review-action@v1 - with: - snap: ${{ steps.build.outputs.snap }} - isClassic: 'false' - - - name: Publish the built snap - id: publish - env: - SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_STORE_CANDIDATE }} - SNAP_FILE: ${{ steps.build.outputs.snap }} - ARCHITECTURE: ${{ matrix.architecture }} - run: | - snapcraft push "$SNAP_FILE" --release="$CHANNEL" - - # Create an issue using the template that asks maintainers to test the snap, and take - # action to promote the revisions to stable if testing is successful. - create_issue: - name: "Create call for testing" - environment: "Candidate Branch" - needs: build - runs-on: ubuntu-latest - steps: - - name: Checkout the source - uses: actions/checkout@v4 - - - name: Setup snapcraft - run: | - sudo snap install snapcraft --classic - - - name: Write the arch/rev table - env: - SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_STORE_CANDIDATE }} - id: build - run: | - # Build the initial structure for the HTML table including the header row. - table="" - - # Declare an array to keep track of the revisions we've seen - revisions=() - - # Iterate over the architectures specified in the snapcraft.yaml - for arch in $(cat snap/snapcraft.yaml | yq '.architectures[]'); do - rev="$(snapcraft list-revisions "${{ env.SNAP_NAME }}" --arch "$arch" | grep "latest/candidate*" | head -n1 | cut -d' ' -f1)" - revisions+=("$rev") - # Add a row to the HTML table - table="${table}" - done - - # Add the closing tags for the table - table="${table}
CPU ArchitectureRevision
${arch}${rev}
" - - # Get a comma separated list of revisions - printf -v joined '%s,' "${revisions[@]}" - - echo "revisions=${joined%,}" >> "$GITHUB_OUTPUT" - echo "table=${table}" >> "$GITHUB_OUTPUT" - - - name: Create call for testing issue - uses: JasonEtco/create-an-issue@v2 - id: comment - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - revisions: ${{ steps.build.outputs.revisions }} - table: ${{ steps.build.outputs.table }} - version: ${{ needs.build.outputs.version }} - with: - filename: .github/testing-issue-template.md - outputs: - issue_number: ${{ steps.comment.outputs.number }} - - # Deploy the snap inside a desktop VM and grab screenshots of the desktop, and of - # the application, then post them as a comment on the issue created above. - grab-screenshots: - name: Gather screenshots - environment: "Candidate Branch" - needs: - - build - - create_issue - runs-on: ubuntu-latest - steps: - - name: Checkout the code - uses: actions/checkout@v4 - - - name: Setup LXD - uses: canonical/setup-lxd@v0.1.1 - - - name: Prepare VM - run: | - .github/vmctl prepare - .github/vmctl exec "sudo snap install ${{ env.SNAP_NAME }} --channel candidate" - .github/vmctl exec "snap run ${{ env.SNAP_NAME }} &>/home/ubuntu/${{ env.SNAP_NAME }}.log &" - sleep 20 - - - name: Gather screenshots - run: | - .github/vmctl screenshot-full - .github/vmctl screenshot-window - - - name: Output application logs - run: | - .github/vmctl exec "cat /home/ubuntu/${{ env.SNAP_NAME }}.log" - - - name: Checkout snapcrafters/ci-screenshots - uses: actions/checkout@v4 - with: - repository: snapcrafters/ci-screenshots - path: ci-screenshots - token: ${{ secrets.SNAPCRAFTERS_BOT_COMMIT }} - - - name: Upload screenshots to snapcrafters/ci-screenshots - id: screenshots - run: | - file_prefix="$(date +%Y%m%d)-${{ env.SNAP_NAME }}-${{ needs.create_issue.outputs.issue_number }}" - - pushd ci-screenshots - mv ../screenshot-screen.png "${file_prefix}-screen.png" - mv ../screenshot-window.png "${file_prefix}-window.png" - - git config --global user.email "merlijn.sebrechts+snapcrafters-bot@gmail.com" - git config --global user.name "Snapcrafters Bot" - - git add -A . - git commit -m "data: screenshots for snapcrafters/${{ env.SNAP_NAME }}#${{ needs.create_issue.outputs.issue_number }}" - git push origin main - - echo "screen=https://raw.githubusercontent.com/snapcrafters/ci-screenshots/main/${file_prefix}-screen.png" >> "$GITHUB_OUTPUT" - echo "window=https://raw.githubusercontent.com/snapcrafters/ci-screenshots/main/${file_prefix}-window.png" >> "$GITHUB_OUTPUT" - - - name: Comment on call for testing issue with screenshots - uses: actions/github-script@v7 - with: - script: | - github.rest.issues.createComment({ - issue_number: ${{ needs.create_issue.outputs.issue_number }}, - owner: context.repo.owner, - repo: context.repo.repo, - body: `The following screenshots were taken during automated testing: - - ![window](${{ steps.screenshots.outputs.window }}) - - ![screen](${{ steps.screenshots.outputs.screen }}) - ` - }) diff --git a/.github/workflows/sync-version-with-upstream.yml b/.github/workflows/sync-version-with-upstream.yml index 01a9caf..a9c5e6b 100644 --- a/.github/workflows/sync-version-with-upstream.yml +++ b/.github/workflows/sync-version-with-upstream.yml @@ -1,4 +1,4 @@ -name: ๐Ÿ”„ Sync version with upstream +name: Update on: # Runs at 10:00 UTC every day @@ -7,34 +7,22 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - sync-version: - name: "Update snapcraft.yaml" + sync: + name: ๐Ÿ”„ Sync version with upstream environment: "Candidate Branch" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: ๐Ÿ”„ Sync version with upstream + uses: snapcrafters/ci/sync-version@main with: token: ${{ secrets.SNAPCRAFTERS_BOT_COMMIT }} - - name: Fetch release version - run: | - VERSION=$( - curl -sL https://api.github.com/repos/mattermost/desktop/releases | - jq . | grep tag_name | grep -v beta | grep -v rc | head -n 1 | cut -d'"' -f4 | tr -d 'v' - ) - sed -i 's/^\(version: \).*$/\1'"$VERSION"'/' snap/snapcraft.yaml - - name: Check for modified files - id: git-check - run: | - MODIFIED=$([ -z "`git status --porcelain`" ] && echo "false" || echo "true") - echo "modified=$MODIFIED" >> $GITHUB_OUTPUT - - name: Commit latest release version - if: steps.git-check.outputs.modified == 'true' - run: | - git config --global user.name 'Snapcrafters Bot' - git config --global user.email 'merlijn.sebrechts+snapcrafters-bot@gmail.com' - git commit -am "Automatic sync to latest release" - git push - outputs: - modified: ${{ steps.git-check.outputs.modified }} + update-script: | + VERSION=$(curl -sL https://api.github.com/repos/mattermost/desktop/releases | + jq . | grep tag_name | grep -v beta | grep -v rc | head -n 1 | cut -d'"' -f4 | tr -d 'v' + ) + sed -i 's/^\(version: \).*$/\1'"$VERSION"'/' snap/snapcraft.yaml diff --git a/.github/workflows/test-snap-can-build.yml b/.github/workflows/test-snap-can-build.yml deleted file mode 100644 index ce482a8..0000000 --- a/.github/workflows/test-snap-can-build.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: ๐Ÿงช Test snap can be built on x86_64 - -on: - pull_request: - branches: [ "**" ] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -# Permissions for GITHUB_TOKEN -permissions: - contents: read - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Build snap - uses: snapcore/action-build@v1 - id: build - - - name: Review snap - uses: diddlesnaps/snapcraft-review-action@v1 - with: - snap: ${{ steps.build.outputs.snap }} - isClassic: 'false'