github.com/openshift-online/ocm-sdk-go@v0.1.473/hooks/pre-push (about)

     1  #!/bin/bash
     2  
     3  #
     4  # Git pre-push hook to validate that tag versions match the Version constant in version.go
     5  #
     6  # This hook is called with the following parameters:
     7  # $1 -- Name of the remote to which the push is being done
     8  # $2 -- URL to which the push is being done
     9  #
    10  # Information about the commits which are being pushed is supplied as lines to
    11  # the standard input in the form:
    12  #   <local ref> <local sha1> <remote ref> <remote sha1>
    13  #
    14  
    15  set -euo pipefail
    16  
    17  print_error() {
    18      echo "ERROR: $1" >&2
    19  }
    20  
    21  print_warning() {
    22      echo "WARNING: $1" >&2
    23  }
    24  
    25  print_info() {
    26      echo "INFO: $1" >&2
    27  }
    28  
    29  # Function to extract version from version.go
    30  get_version_from_file() {
    31      if [[ ! -f "version.go" ]]; then
    32          print_error "version.go file not found"
    33          print_error "Make sure you are running this command from the root of the repository"
    34          return 1
    35      fi
    36  
    37      # Extract version using grep and sed
    38      local version=$(grep -E '^const Version = ' version.go | sed -E 's/^const Version = "([^"]+)".*$/\1/')
    39  
    40      if [[ -z "$version" ]]; then
    41          print_error "Could not extract version from version.go"
    42          return 1
    43      fi
    44  
    45      echo "$version"
    46  }
    47  
    48  # Function to check if a ref is a version tag
    49  is_version_tag() {
    50      local ref="$1"
    51      if [[ "$ref" == refs/tags/* ]]; then
    52          local tag_name="${ref#refs/tags/}"
    53          # Match ONLY pattern vX.Y.Z (e.g., v0.1.472, v1.2.3)
    54          [[ "$tag_name" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]
    55      else
    56          return 1
    57      fi
    58  }
    59  
    60  # Function to check if a tag has a message starting with 'Release'
    61  is_release_tag() {
    62      local ref="$1"
    63      if [[ "$ref" == refs/tags/* ]]; then
    64          local tag_name="${ref#refs/tags/}"
    65          # Get the tag message (first line)
    66          local tag_message=$(git tag -l --format='%(contents:lines=1)' "$tag_name" 2>/dev/null || echo "")
    67          [[ "$tag_message" =~ ^Release.* ]]
    68      else
    69          return 1
    70      fi
    71  }
    72  
    73  # Function to extract version from tag name
    74  get_version_from_tag() {
    75      local tag="$1"
    76      # Remove refs/tags/ prefix and v prefix if present
    77      local version="${tag#refs/tags/}"
    78      version="${version#v}"
    79      echo "$version"
    80  }
    81  
    82  # Function to validate tag version against version.go
    83  validate_tag_version() {
    84      local tag_ref="$1"
    85      local tag_version
    86      local file_version
    87  
    88      tag_version=$(get_version_from_tag "$tag_ref")
    89      file_version=$(get_version_from_file)
    90  
    91      print_info "Validating tag version..."
    92      print_info "  Tag version:  $tag_version"
    93      print_info "  File version: $file_version"
    94  
    95      if [[ "$tag_version" != "$file_version" ]]; then
    96          print_error "Version mismatch detected!"
    97          print_error "  Tag version:      $tag_version"
    98          print_error "  version.go const: $file_version"
    99          print_error ""
   100          print_error "Please update the Version constant in version.go to match the tag"
   101          print_error "or use a tag that matches the current version in version.go"
   102          print_error ""
   103          print_error "To fix this:"
   104          print_error "  1. Update version.go: const Version = \"$tag_version\""
   105          print_error "  2. Commit the change"
   106          print_error "  3. Push again"
   107          return 1
   108      fi
   109      print_info "Version validation passed!"
   110      return 0
   111  }
   112  
   113  # Read the refs being pushed from stdin
   114  while read local_ref local_sha remote_ref remote_sha; do
   115      # Skip if we're deleting a ref
   116      if [[ "$local_sha" == "0000000000000000000000000000000000000000" ]]; then
   117          continue
   118      fi
   119      # Check if this is a version tag being pushed
   120      if is_version_tag "$remote_ref"; then
   121          print_info "Detected version tag push: $remote_ref"
   122          # Check if this is a release tag (message starts with 'Release')
   123          if is_release_tag "$remote_ref"; then
   124              print_info "Tag has 'Release' message - validating version consistency"
   125              # Validate the tag version
   126              if ! validate_tag_version "$remote_ref"; then
   127                  exit 1
   128              fi
   129          else
   130              print_info "Tag does not have 'Release' message - skipping validation"
   131          fi
   132      fi
   133  done
   134  
   135  print_info "Pre-push validation completed successfully"
   136  exit 0