Skip to content

Conversation

@ozer550
Copy link
Member

@ozer550 ozer550 commented Sep 29, 2025

Summary

  • GitHub Actions workflow with 4 stages: version check -> build -> copy -> manual approval -> promote
  • Automated promotion from kolibri-proposed to kolibri PPA.

Setup Steps

Create GitHub Environment:

  • Go to repository Settings -> Environments -> New environment
  • Name: release
  • Add required reviewers
  • Save environment.

Generate Launchpad Credentials:

  • Install launchpadlib: pip install launchpadlib
  • Edit paths in scripts/create_lp_creds.py:
CACHE_DIR - your preferred cache location
CREDS_FILE - where to save credentials
  • Run: python scripts/create_lp_creds.py
  • Approve permissions in browser

Add GitHub Secrets:

  • Go to Settings -> Secrets and variables -> Actions
    Add repository secrets:
LP_CREDENTIALS - content of launchpad.credentials file
GPG_SIGNING_KEY - your GPG private key (base64 encoded)
GPG_PASSPHRASE - GPG key passphrase
GPG_KEY_ID - your GPG key ID

References

closes #102

Reviewer guidance


@ozer550 ozer550 marked this pull request as ready for review October 6, 2025 15:08
@rtibbles rtibbles self-assigned this Oct 6, 2025
Copy link
Member

@rtibbles rtibbles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we probably need to have the full version name.

I also have some questions about some parts of the launchpad lib usage.

- name: Extract version from changelog
id: changelog_version
run: |
CHANGELOG_VERSION=$(dpkg-parsechangelog -S Version | sed -rne 's,([^-\+]+)+(\+dfsg)*.*,\1,p'i)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should require that the version information include the fully specified version? So something like 0.5.0-0ubuntu2 - otherwise we wouldn't be able to trigger a 'packaging only' release using this workflow.

- name: Extract version from release tag
id: version
run:
VERSION=${GITHUB_REF#refs/tags/v}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This syntax for removing the leading text from a variable was new to me, neat!

- name: Import GPG key
run: |
echo -n "${{ secrets.GPG_SIGNING_KEY }}" | base64 --decode | gpg --import --no-tty --batch --yes
- name: Build unsigned package
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these need to be separate steps?

env:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
run: |
echo "Building unsigned package..."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe let's move any relevant echo comments into the Makefile?

Makefile Outdated
dpkg-buildpackage -S -us -uc --output-directory=dist/

# build and sign (signing uses environment GPG_PASSPHRASE and KEYID)
sign-and-dist:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add dist as a required build step for this, and that would allow us just to call sign-and-dist in the workflow? Feels like the name implies it would do both!


def get_launchpad_client():
cache_dir = os.environ.get("LP_CACHE_DIR", "/tmp/launchpadlib-cache")
creds_file = os.environ.get("LP_CREDENTIALS_FILE") # set by CI
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the launchpadlib itself already uses this env var, without us having to intercept and pass through? https://git.launchpad.net/launchpadlib/tree/src/launchpadlib/launchpad.py#n535


def get_supported_series_dynamically(source_series):
try:
out = subprocess.check_output(["ubuntu-distro-info", "--supported", "--series"], text=True).strip()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running this command: ubuntu-distro-info --supported --series

Gave me this output:
ubuntu-distro-info: option --series' requires an argument SERIES`

I think just ubuntu-distro-info --supported will do for now? We may want to expand it later, but I'm not exactly sure how we want to do that!

def install_request_counter():
import httplib2
orig = httplib2.Http.request

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is just your IDE adding this formatting - maybe we should add pre-commit at some point?


class LaunchpadWrapper(object):
application_name = 'ppa-gtimelog-copy-packages'
application_name = 'ppa-kolibri-server-copy-packages'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we know where we stole this from originally now!

CACHE_DIR = "/absolute/path/to/lp-cache"
CREDS_FILE = "/absolute/path/to/launchpad.credentials"

Launchpad.login_with(APP_NAME, "production", cache_dir=CACHE_DIR, credentials_file=CREDS_FILE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just output this to the current working directory rather than an absolute path? Also see above for my comment about the cache dir.

@ozer550 ozer550 requested a review from rtibbles October 14, 2025 15:09
Copy link
Member

@rtibbles rtibbles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've done all we can in review - next test will be doing it live!

@rtibbles rtibbles merged commit b785ee9 into learningequality:main Nov 26, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automate releases using Github releases

2 participants