Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add workflow for auto updating submodules and submitting a PR #302

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions .github/scripts/google-skywater-pdk-roll.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/env python3
# Copyright 2020 SkyWater PDK Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

# Originally written by Tim 'mithro' Ansell
# Slightly modified for Github Actions use by Amr Gouhar (agorararmard)

import datetime
import os
import pprint
import subprocess
import sys
import tempfile
import textwrap
import argparse

now = datetime.datetime.utcnow()
now = now.replace(microsecond=0)

subprocess.check_call(['git', 'reset', '--hard'])
subprocess.check_call(['git', 'submodule', 'update', '--init'])

parser = argparse.ArgumentParser(
description="Update submodules and create a commit")
parser.add_argument('--libraries_dir', '-l', action='store', default='libraries',
help="Libraries Directory")

args = parser.parse_args()

libdir = os.path.abspath(args.libraries_dir)

changes = []

for lib in sorted(os.listdir(libdir)):
ldir = os.path.join(libdir, lib)
for v in sorted(os.listdir(ldir)):
submod = os.path.join(ldir, v)

if v == 'latest':
branch = 'master'
else:
assert v.startswith('v'), v
branch = 'branch-'+v[1:]

gitdir = os.path.join(submod, '.git')
assert os.path.exists(gitdir), gitdir

print('\n\n')
print(v + " " + submod + " "+ branch)
print('\n')
subprocess.call( ['git', 'branch', '-D', branch], cwd=submod)
subprocess.call( ['git', 'branch', '-D', 'origin/'+branch], cwd=submod)
# Need unshallow and tags so git-describe works
subprocess.check_call(['git', 'remote', '-v'], cwd=submod)
subprocess.call( ['git', 'fetch', 'origin', '--prune', '--prune-tags'], cwd=submod)
subprocess.call( ['git', 'fetch', '--progress', 'origin', '--unshallow'], cwd=submod)
subprocess.check_call(['git', 'fetch', '--progress', 'origin', '--tags'], cwd=submod)
subprocess.check_call(['git', 'fetch', '--progress', 'origin', '+{0}:remotes/origin/{0}'.format(branch)], cwd=submod)

old_version = subprocess.check_output(['git', 'describe'], cwd=submod).decode('utf-8').strip()

subprocess.check_call(['git', 'status'], cwd=submod)
subprocess.check_call(['git', 'branch', '-av'], cwd=submod)
subprocess.check_call(['git', 'reset', '--hard', 'origin/'+branch], cwd=submod)

new_version = subprocess.check_output(['git', 'describe'], cwd=submod).decode('utf-8').strip()
print(old_version + '-->' + new_version)

log = subprocess.check_output(['git', 'log', '--graph', '--pretty=short', '--decorate=short', '--decorate-refs=remotes/origin', '--shortstat', old_version+'..'+new_version], cwd=submod).decode('utf-8')

print('\n\n\n\n')
print(lib + ' ' + v)
print('\n')
print('-'*10)
print('-'*10)
print('\n')
print(subprocess.check_output(['git', 'log', '--pretty=short', '--decorate=short', '--decorate-refs=remotes/origin', old_version+'..'+new_version], cwd=submod).decode('utf-8'))
print('\n')
print('-'*10)
print('\n')
print(log)
print('-'*10)

changes.append((lib, v, old_version, new_version))
subprocess.check_call(['git', 'add', v], cwd=ldir)


def get_submod_info():
output = subprocess.check_output(['git', 'submodule', 'summary']).decode('utf-8')
output = output.replace('\n\n\n', '\n\n')
output = output.strip()
return textwrap.indent(output, ' ')

print('\n\n')
print('-'*75)
subprocess.check_call(['git', 'status'])
print('-'*75)
pprint.pprint(changes)
print('-'*75)

output = ['Updating submodules on {} UTC'.format(now), '']

for lib, ver, ov, nv in changes:
if ov == nv:
continue
output.append('''\
- Updating [`{lib}` {ver}](https://github.com/google/skywater-pdk-libs-{lib}/compare/{ov}..{nv}) to {nv}'''.format(
lib=lib, ver=ver, ov=ov, nv=nv))

output.append('')
output.append(get_submod_info())

print('\n'.join(output))


with tempfile.NamedTemporaryFile('w') as f:
f.write('\n'.join(output))
f.flush()
subprocess.check_call(['git', 'commit', '--signoff', '--file={}'.format(f.name)])

40 changes: 40 additions & 0 deletions .github/workflows/auto-pr-submodules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Update Submodules and Submit a PR

on:
workflow_dispatch:
push:
branches:
- master
schedule:
- cron: '0 0 * * *'

jobs:
createPullRequest:
if: contains(github.ref, 'master')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Copy link
Collaborator

Choose a reason for hiding this comment

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

actions/checkout has options for getting submodules too. See https://github.com/actions/checkout/#usage.

It might make sense to suggest option submodules: remote to be added upstream.

Copy link
Author

Choose a reason for hiding this comment

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

Wouldn't hurt I guess.

Copy link
Contributor

Choose a reason for hiding this comment

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

submodules: remote?

Copy link
Contributor

Choose a reason for hiding this comment

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

BTW We probably want a "Treeless clone" otherwise the worker will run out of disk space?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@mithro, in this PR git submodule update --remote is executed after checkout, in order to update all submodules to their heads/master/main. That is required because actions/checkout does not support such feature. Hence, I was suggesting that maintainers of the action might want to add the feature.

Copy link
Author

Choose a reason for hiding this comment

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

@mithro: Yeah, with the current setup a Github-hosted runner will definitely run out of disk space. But would a treeless clone help here tho (I'm trying it out locally right now)?

Copy link
Author

Choose a reason for hiding this comment

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

@mithro, @umarcor: I'm afraid a treeless clone won't cut it (unless I'm doing it wrong). We will need a self-hosted runner to do this. However, since this workflow will only run on internal pushes, there are no security concerns regarding the protection of the self-hosted runner against pull-requests. In other words, this can be any machine.

After running the script to update submodules, after git clone --filter=tree:0 ....:

du -sh skywater-pdk/
53G	skywater-pdk/


- name: Update Submodules to Remote Latest
run: python3 .github/scripts/google-skywater-pdk-roll.py -l libraries

- name: Export Body
run: echo "BODY=$(git log -1 --pretty=%B)" >> $GITHUB_ENV

- name: Export First 5 Digits of Commit Hash
run: echo "COMMIT_SHA_5=$(echo ${{ github.sha }} | awk '{print substr($0,0,5)}')" >> $GITHUB_ENV

- name: Export Title
run: echo "TITLE='Update Submodules to Remote Latest, triggered from commit ${{ env.COMMIT_SHA_5 }}'" >> $GITHUB_ENV

- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ github.token }}
title: ${{ env.TITLE }}
branch: create-pull-request/submodules-auto-update
base: master
delete-branch: true
body: ${{ env.BODY }}
labels: update submodules, automated pr