Source code for action_updater.main.updaters.version.update

__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2022, Vanessa Sochat"
__license__ = "MPL 2.0"

from action_updater.main.github import sort_major, sort_tags
from action_updater.main.updater import UpdaterBase

schema = {
    "type": "object",
    "properties": {
        # Allow these orgs to use major version strings
        "major_orgs": {"type": "array", "items": {"type": "string"}}
    },
    "additionalProperties": False,
}


[docs]class VersionUpdater(UpdaterBase): name = "version" description = "update action versions" schema = schema cache = {"tags": {}}
[docs] def detect(self, action): """ Detect changes (to be later saved) """ # Set the count to 0 self.count = 0 # No point if we don't have jobs! if not action.steps: return False # We will use major versions for these orgs (trusted) trusted_orgs = self.settings.get("major_orgs") # For each job, look for steps->updater versions for step in action.steps: # We are primarily interested in uses if "uses" not in step: continue repo = step["uses"] # If we have a local action, nothing to update if repo.startswith("./"): continue # Get the current tag or version (we will want to maintain this convention) # Create a lookup based on the ref repo, _ = repo.split("@") org, _ = repo.split("/", 1) # Retrieve all tags for the repository, a lookup by tag name tags = self.cache["tags"].get(repo) or self.get_tags_lookup(repo) updated = None if trusted_orgs and org in trusted_orgs: updated = self.get_major_tag(tags) if not updated: updated = self.get_tagged_commit(tags) # Save repo tags in cache self.cache["tags"][repo] = tags # If we don't have tags by this point, no go - we cannot parse if not updated: continue updated = f"{repo}@{updated}" previous = step["uses"] # If we added a new comment, update the old one if "#" in updated: updated, comment = updated.split("#", 1) comment = comment.strip() step["uses"] = updated.strip() # TODO some check to preserve other previous comments? step.ca.items["uses"] = [None, None, None, None] # Add the end of line comment (third position in list) step.yaml_add_eol_comment(f"# {comment}\n", "uses", column=0) # Always do the update (regardless of comment!) step["uses"] = updated.strip() # Do we have a change? if step["uses"] != previous: self.count += 1 return self.count != 0
[docs] def get_major_tag(self, tags): """ Given a list of repository tags, get the most up-todate! """ # If we have a major org, we trust it and want the major version tag tags_list = list(tags) tags_list = [x for x in tags_list if "." not in x] # Cut out early if we don't have major-only tags if not tags_list: return [] # Get ordered major tags ordered = sort_major(tags_list) # If we don't have ordered, we could use branches, but skip for now if not ordered: return [] tag = ordered[0]._original # Use latest release verbatim return tag
[docs] def get_tagged_commit(self, tags): """ Given a list of repository tags, get the most up-todate! """ # Get ordered major tags ordered = sort_tags(list(tags)) # First pass - no ordered tags, try to do the same for the major versions if not ordered: ordered = sort_major(tags) # If we don't have ordered, we could use branches, but skip for now if not ordered: return [] tag = ordered[0]._original meta = tags[tag] commit = meta["object"]["sha"] return f"{commit} # {tag}"